General Setup


Create a new analysis directories.

- general directory

- for plots

- for output of summary results

- for baseline tables

- for genetic analyses

- for Cox regression results
source("scripts/functions.R")
source("scripts/pack01.packages.R")

* General packages...

Today = format(as.Date(as.POSIXlt(Sys.time())), "%Y%m%d")
Today.Report = format(as.Date(as.POSIXlt(Sys.time())), "%A, %B %d, %Y")

source("scripts/colors.R")

Background

Collaboration to study PCSK9 in relation to atherosclerotic plaques characteristics.

  • Genes.xlsx - list of genes of interest.
  • Variants.xlsx - list of variant(s) of interest.
library(openxlsx)

gene_list_df <- read.xlsx(paste0(TARGET_loc, "/targets.xlsx"), sheet = "Genes")

gene_list <- unlist(gene_list_df$Gene)
gene_list
[1] "CXCL10" "PCSK9"  "COL4A1" "COL4A2" "COL3A"  "COL2A"  "LDLR"   "CD36"  
variant_list <- read.xlsx(paste0(TARGET_loc, "/targets.xlsx"), sheet = "Variants")

DT::datatable(variant_list)
NA

This notebook

In this notebook we setup the files for the SNP analysis.

Athero-Express Biobank Study

The Athero-Express Biobank Study (AE) contains plaque material of patients that underwent endarterectomyat two Dutch tertiary referral centers. Details of the study design were described before. Briefly, blood and plaque material were obtained during endarterectomy and stored at -80 ℃. Only carotid endarterectomy (CEA) patients were included in the present study. All patients provided informed consent and the study was approved by the medical ethics committee.

Athero-Express Genomics Study

DNA isolation and genotyping

We genotyped the AE in three separate, but consecutive experiments. In short, DNA was extracted from EDTA blood or (when no blood was available) plaque samples of 1,858 consecutive patients from the Athero-Express Biobank Study and genotyped in 3 batches.

For the Athero-Express Genomics Study 1 (AEGS1) 891 patients (602 males, 262 females, 27 unknown sex), included between 2002 and 2007, were genotyped (440,763 markers) using the Affymetrix Genome-Wide Human SNP Array 5.0 (SNP5) chip (Affymetrix Inc., Santa Clara, CA, USA) at Eurofins Genomics (formerly known as AROS).

For the Athero-Express Genomics Study 2 (AEGS2) 954 patients (640 makes, 313 females, 1 unknown sex), included between 2002 and 2013, were genotyped (587,351 markers) using the Affymetrix AxiomⓇ GW CEU 1 Array (AxM) at the Genome Analysis Center.

For the Athero-Express Genomics Study 3 (AEGS3) 658 patients (448 males, 203 females, 5 unknown sex), included between 2002 and 2016, were genotyped (693,931 markers) using the Illumina GSA MD v1 BeadArray (GSA) at Human Genomics Facility, HUGE-F.

All experiments were carried out according to OECD standards.

Genotyping calling

We used the genotyping calling algorithms as advised by Affymetrix (AEGS1 and AEGS2) and Illumina (AEGS3):

  • AEGS1: BRLMM-P
  • AEGS2: AxiomGT1
  • AEGS3: Illumina GenomeStudio

Quality control after genotyping

After genotype calling, we adhered to community standard quality control and assurance (QCA) procedures of the genotype data from AEGS1, AEGS2, and AEGS3. Samples with low average genotype calling and sex discrepancies (compared to the clinical data available) were excluded. The data was further filtered on:

  1. individual (sample) call rate > 97%,
  2. SNP call rate > 97%,
  3. minor allele frequencies (MAF) > 3%,
  4. average heterozygosity rate ± 3.0 s.d.,
  5. relatedness (pi-hat > 0.20),
  6. Hardy–Weinberg Equilibrium (HWE p < 1.0×10−3<>), and
  7. Monomorphic SNPs (< 1.0×10−6<>).

After QCA 2,493 samples remained, 108 of non-European descent/ancestry, and 156 related pairs. These comprise 890 samples and 407,712 SNPs in AEGS1, 869 samples and 534,508 SNPs in AEGS2, and 649954 samples and 534,508 SNPs in AEGS3 remained.

Imputation

Before phasing using SHAPEIT2, data was lifted to genome build b37 using the liftOver tool from UCSC (https://genome.ucsc.edu/cgi-bin/hgLiftOver). Finally, data was imputed with 1000G phase 3, version 5 and HRC release 1.1 as a reference using the Michigan Imputation Server. These results were further integrated using QCTOOL v2, where HRC imputed variants are given precendence over 1000G phase 3 imputed variants.

Quality control after imputation

We compared quality of the three AEGS datasets, and listed some variables of interest.

  • sample type (EDTA blood or plaque)
  • genotyping chip used
  • reason for filtering

We checked the studytype (AE or not), and identity-by-descent (IBD) within and between datasets to aid in sample mixups, duplicate sample use, and relatedness. In addition, during genotyping quality control samples were identified that deviated from Hardy-Weinberg Equilibrium (HWE), had discordance in sex-coding and genotype sex, and deviated from the principal component analysis (PCA) plot.

We will load the Athero-Express Biobank Study data, and all the samples that were send for genotyping and the final QC’ed sampleList.

Loading data

Loading Athero-Express Biobank Study clinical and biobank data, as well as the SampleList of genetic data. We simply load the previously saved RDS-file and extract the clinical data from that.

cat("* get Athero-Express Biobank Study Database...\n")
* get Athero-Express Biobank Study Database...
AEDB.CEA <- readRDS(file = paste0(OUT_loc, "/20230614.",TRAIT_OF_INTEREST,".AEDB.CEA.RDS"))
AEDB.CEA[1:10, 1:10]
dim(AEDB.CEA)
[1] 2595 1201
AEDB.full <- readRDS(file = paste0(OUT_loc, "/20230614.",TRAIT_OF_INTEREST,".AEDB.FULL.RDS"))
AEDB.full[1:10, 1:10]
dim(AEDB.full)
[1] 3673 1201
cat("\n* get Athero-Express Genomics Study keys...\n")

* get Athero-Express Genomics Study keys...
AEGS123.sampleList.keytable <- fread(paste0(AEGSQC_loc, "/QC/SELECTIONS/20200419.QC.AEGS123.sampleList.keytable.txt"))

dim(AEGS123.sampleList.keytable)
[1] 2124   25
# AEGS123.sampleList.keytable[1:10, 1:10]

Athero-Express Genomics Study

Prepare baseline

Let’s combine the full Athero-Express Biobank Study with the key-table containing the AEGS data.

NOTE: this should sum to 2,124 samples with genotypes.

AEGS <- merge(AEDB.full, AEGS123.sampleList.keytable, by.x = "STUDY_NUMBER", by.y = "STUDY_NUMBER", sort = FALSE,
                  all = TRUE)

dim(AEGS)
[1] 3791 1225
AEGS$UPID.y <- NULL
names(AEGS)[names(AEGS) == "UPID.x"] <- "UPID"
AEGS$Age.y <- NULL
names(AEGS)[names(AEGS) == "Age.x"] <- "Age"

table(AEGS$CHIP, useNA = "ifany")

AffyAxiomCEU     AffySNP5       IllGSA         <NA> 
         918          687          519         1667 
AEGS$GWAS <- AEGS$CHIP
AEGS$GWAS[is.na(AEGS$GWAS)] <- "not genotyped"
AEGS$GWAS[AEGS$GWAS != "not genotyped"] <- "genotyped"

table(AEGS$CHIP, AEGS$GWAS, useNA = "ifany")
              
               genotyped not genotyped
  AffyAxiomCEU       918             0
  AffySNP5           687             0
  IllGSA             519             0
  <NA>                 0          1667

Also a visualisation of the AEGS with AEDB overlaps.

library(UpSetR)
require(ggplot2)
require(plyr)
require(gridExtra)
require(grid)

AEDB.availGWAS = list(
AEGS1 = subset(AEGS, CHIP == "AffySNP5", select = c("STUDY_NUMBER"))[,1],
AEGS2 = subset(AEGS, CHIP == "AffyAxiomCEU", select = c("STUDY_NUMBER"))[,1],
AEGS3 = subset(AEGS, CHIP == "IllGSA", select = c("STUDY_NUMBER"))[,1],
AEDB = AEGS$STUDY_NUMBER)

p1 <- UpSetR::upset(fromList(AEDB.availGWAS), 
                    sets = c("AEDB", "AEGS1", "AEGS2", "AEGS3"), 
                    main.bar.color = c(uithof_color[15], uithof_color[3], uithof_color[2], uithof_color[21]), 
                    mainbar.y.label = "intersection sample size", 
                    sets.bar.color = c(uithof_color[15], uithof_color[2], uithof_color[3], uithof_color[21]), 
                    sets.x.label = "sample size", keep.order = TRUE)

p1


pdf(paste0(PLOT_loc, "/", Today, ".overlap.AEDB_AEGS123.UpSetR.pdf"))
  p1
dev.off()
quartz_off_screen 
                2 
png(paste0(PLOT_loc, "/", Today, ".overlap.AEDB_AEGS123.UpSetR.png"))
  p1
dev.off()
quartz_off_screen 
                2 

rm(p1)

Please refer to the AEDB.CEA.baseline.html document for the details on the informed consent selection.

table(AEGS$Artery_summary, AEGS$QC2018_FILTER)
                                                                                         
                                                                                          family_discard family_keep issue passed
  No artery known (yet), no surgery (patient ill, died, exited study), re-numbered to AAA              0           0     0      0
  carotid (left & right)                                                                              20          21    40   1814
  femoral/iliac (left, right or both sides)                                                            1           0     0     99
  other carotid arteries (common, external)                                                            0           0     0      9
  carotid bypass and injury (left, right or both sides)                                                0           0     0      1
  aneurysmata (carotid & femoral)                                                                      0           0     0      0
  aorta                                                                                                0           0     0      0
  other arteries (renal, popliteal, vertebral)                                                         0           0     0      1
  femoral bypass, angioseal and injury (left, right or both sides)                                     0           0     0      0
table(AEGS$informedconsent, AEGS$QC2018_FILTER)
                                                                                                 
                                                                                                  family_discard family_keep issue passed
  missing                                                                                                      0           0     0      0
  no, died                                                                                                     0           0     0      0
  yes                                                                                                         17          16    24   1411
  yes, health treatment when possible                                                                          2           2    10    312
  yes, no health treatment                                                                                     2           2     2     91
  yes, no health treatment, no commercial business                                                             0           0     0     15
  yes, no tissue, no commerical business                                                                       0           0     0      0
  yes, no tissue, no questionnaires, no medical info, no commercial business                                   0           0     0      0
  yes, no questionnaires, no health treatment, no commercial business                                          0           0     0      1
  yes, no questionnaires, health treatment when possible                                                       0           0     0      2
  yes, no tissue, no questionnaires, no health treatment, no commerical business                               0           0     0      0
  yes, no health treatment, no medical info, no commercial business                                            0           0     3     10
  yes, no tissue, no questionnaires, no health treatment, no medical info, no commercial business              0           0     0      0
  yes, no questionnaires, no health treatment                                                                  0           0     0      0
  yes, no tissue, no health treatment                                                                          0           0     0      0
  yes, no tissue, no questionnaires                                                                            0           0     0      0
  yes, no tissue, health treatment when possible                                                               0           0     0      0
  yes, no tissue                                                                                               0           0     0      0
  yes, no commerical business                                                                                  0           1     0     35
  yes, health treatment when possible, no commercial business                                                  0           0     0     25
  yes, no medical info, no commercial business                                                                 0           0     0      4
  yes, no questionnaires                                                                                       0           0     0      1
  yes, no tissue, no questionnaires, no health treatment, no medical info                                      0           0     0      0
  yes, no tissue, no questionnaires, no health treatment, no commercial business                               0           0     0      0
  yes, no medical info                                                                                         0           0     1      5
  yes, no questionnaires, no commercial business                                                               0           0     0      0
  yes, no questionnaires, no health treatment, no medical info                                                 0           0     0      1
  yes, no questionnaires, health treatment when possible, no commercial business                               0           0     0      0
  yes,  no health treatment, no medical info                                                                   0           0     0      5
  no, doesn't want to                                                                                          0           0     0      0
  no, unable to sign                                                                                           0           0     0      0
  no, no reaction                                                                                              0           0     0      0
  no, lost                                                                                                     0           0     0      0
  no, too old                                                                                                  0           0     0      0
  yes, no medical info, health treatment when possible                                                         0           0     0      2
  no (never asked for IC because there was no tissue)                                                          0           0     0      0
  yes, no medical info, no commercial business, health treatment when possible                                 0           0     0      2
  no, endpoint                                                                                                 0           0     0      0
  wil niets invullen, wel alles gebruiken                                                                      0           0     0      0
  second informed concents: yes, no commercial business                                                        0           0     0      2
  nooit geincludeerd                                                                                           0           0     0      0
  yes, not outside EU                                                                                          0           0     0      0
  yes, no DNA                                                                                                  0           0     0      0
AEGSselect <- subset(AEGS, 
                     informedconsent != "missing" & # we are really strict in selecting based on 'informed consent'!
                     informedconsent != "no, died" & 
                     informedconsent != "yes, no tissue, no commerical business" & 
                     informedconsent != "yes, no tissue, no questionnaires, no medical info, no commercial business" & 
                     informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commerical business" & 
                     informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info, no commercial business" & 
                     informedconsent != "yes, no tissue, no health treatment" & 
                     informedconsent != "yes, no tissue, no questionnaires" & 
                     informedconsent != "yes, no tissue, health treatment when possible" & 
                     informedconsent != "yes, no tissue" & 
                     informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info" & 
                     informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commercial business" & 
                     informedconsent != "no, doesn't want to" & 
                     informedconsent != "no, unable to sign" & 
                     informedconsent != "no, no reaction" & 
                     informedconsent != "no, lost" & 
                     informedconsent != "no, too old" & 
                     informedconsent != "no (never asked for IC because there was no tissue)" & 
                     informedconsent != "no, endpoint" & 
                     informedconsent != "wil niets invullen, wel alles gebruiken" & 
                     informedconsent != "nooit geincludeerd" & 
                     informedconsent != "yes, no DNA")

AEGSselect.CEA <- subset(AEGS, !is.na(QC2018_FILTER) & QC2018_FILTER != "issue" & QC2018_FILTER != "family_discard" &
                     (Artery_summary == "carotid (left & right)" | Artery_summary == "other carotid arteries (common, external)") & # we only want carotids
                     informedconsent != "missing" & # we are really strict in selecting based on 'informed consent'!
                     informedconsent != "no, died" & 
                     informedconsent != "yes, no tissue, no commerical business" & 
                     informedconsent != "yes, no tissue, no questionnaires, no medical info, no commercial business" & 
                     informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commerical business" & 
                     informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info, no commercial business" & 
                     informedconsent != "yes, no tissue, no health treatment" & 
                     informedconsent != "yes, no tissue, no questionnaires" & 
                     informedconsent != "yes, no tissue, health treatment when possible" & 
                     informedconsent != "yes, no tissue" & 
                     informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info" & 
                     informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commercial business" & 
                     informedconsent != "no, doesn't want to" & 
                     informedconsent != "no, unable to sign" & 
                     informedconsent != "no, no reaction" & 
                     informedconsent != "no, lost" & 
                     informedconsent != "no, too old" & 
                     informedconsent != "no (never asked for IC because there was no tissue)" & 
                     informedconsent != "no, endpoint" & 
                     informedconsent != "wil niets invullen, wel alles gebruiken" & 
                     informedconsent != "nooit geincludeerd" & 
                     informedconsent != "yes, no DNA")

dim(AEGSselect)
[1] 3673 1224
table(AEGSselect$Artery_summary, AEGSselect$QC2018_FILTER)
                                                                                         
                                                                                          family_discard family_keep issue passed
  No artery known (yet), no surgery (patient ill, died, exited study), re-numbered to AAA              0           0     0      0
  carotid (left & right)                                                                              20          21    40   1814
  femoral/iliac (left, right or both sides)                                                            1           0     0     99
  other carotid arteries (common, external)                                                            0           0     0      9
  carotid bypass and injury (left, right or both sides)                                                0           0     0      1
  aneurysmata (carotid & femoral)                                                                      0           0     0      0
  aorta                                                                                                0           0     0      0
  other arteries (renal, popliteal, vertebral)                                                         0           0     0      1
  femoral bypass, angioseal and injury (left, right or both sides)                                     0           0     0      0
table(AEGSselect$Artery_summary, AEGSselect$CHIP)
                                                                                         
                                                                                          AffyAxiomCEU AffySNP5 IllGSA
  No artery known (yet), no surgery (patient ill, died, exited study), re-numbered to AAA            0        0      0
  carotid (left & right)                                                                           860      550    485
  femoral/iliac (left, right or both sides)                                                          0       72     28
  other carotid arteries (common, external)                                                          2        5      2
  carotid bypass and injury (left, right or both sides)                                              0        1      0
  aneurysmata (carotid & femoral)                                                                    0        0      0
  aorta                                                                                              0        0      0
  other arteries (renal, popliteal, vertebral)                                                       0        1      0
  femoral bypass, angioseal and injury (left, right or both sides)                                   0        0      0
table(AEGSselect$QC2018_FILTER, AEGSselect$CHIP)
                
                 AffyAxiomCEU AffySNP5 IllGSA
  family_discard           12        6      3
  family_keep               8        1     12
  issue                    37        1      2
  passed                  805      621    498
table(AEGSselect$QC2018_FILTER, AEGSselect$SAMPLE_TYPE)
                
                 EDTA_blood plaque unknown
  family_discard         15      6       0
  family_keep            13      8       0
  issue                  26     14       0
  passed               1200    723       1
AEDB.temp <- subset(AEGSselect,  select = c("STUDY_NUMBER", "UPID", "Age", "Gender", "Hospital", "Artery_summary", "QC2018_FILTER", "CHIP", "SAMPLE_TYPE"))
require(labelled)
AEDB.temp$Gender <- to_factor(AEDB.temp$Gender)
AEDB.temp$Hospital <- to_factor(AEDB.temp$Hospital)
AEDB.temp$Artery_summary <- to_factor(AEDB.temp$Artery_summary)
AEDB.temp$QC2018_FILTER <- to_factor(AEDB.temp$QC2018_FILTER)
AEDB.temp$CHIP <- to_factor(AEDB.temp$CHIP)
AEDB.temp$SAMPLE_TYPE <- to_factor(AEDB.temp$SAMPLE_TYPE)

DT::datatable(AEDB.temp[1:10,], caption = "Excerpt of the whole AEDB.", rownames = FALSE)

rm(AEDB.temp)

Athero-Express Genomics Study Baseline Characteristics

Showing the baseline table of the Athero-Express Genomics Study.

```r
# Create baseline tables
# http://rstudio-pubs-static.s3.amazonaws.com/13321_da314633db924dc78986a850813a50d5.html
AEGSselect$GWAS <- to_factor(AEGSselect$GWAS)
AEGSselect$CHIP <- to_factor(AEGSselect$CHIP)
AEGSselect$PCA <- to_factor(AEGSselect$PCA)
AEGSselect$SAMPLE_TYPE <- to_factor(AEGSselect$SAMPLE_TYPE)
AEGSselect$informedconsent <- to_factor(AEGSselect$informedconsent)

AEGSselect.CEA$GWAS <- to_factor(AEGSselect.CEA$GWAS)
AEGSselect.CEA$CHIP <- to_factor(AEGSselect.CEA$CHIP)
AEGSselect.CEA$PCA <- to_factor(AEGSselect.CEA$PCA)
AEGSselect.CEA$SAMPLE_TYPE <- to_factor(AEGSselect.CEA$SAMPLE_TYPE)
AEGSselect.CEA$informedconsent <- to_factor(AEGSselect.CEA$informedconsent)


cat(\===========================================================================================\n\)

<!-- rnb-source-end -->

<!-- rnb-output-begin eyJkYXRhIjoiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIn0= -->

===========================================================================================




<!-- rnb-output-end -->

<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuY2F0KFxcQ1JFQVRFIEJBU0VMSU5FIFRBQkxFXFxuXFwpXG5gYGBcbmBgYCJ9 -->

```r
```r
cat(\CREATE BASELINE TABLE\n\)

<!-- rnb-source-end -->

<!-- rnb-output-begin eyJkYXRhIjoiQ1JFQVRFIEJBU0VMSU5FIFRBQkxFXG4ifQ== -->

CREATE BASELINE TABLE




<!-- rnb-output-end -->

<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuIyBCYXNlbGluZSB0YWJsZSB2YXJpYWJsZXNcbmJhc2V0YWJsZV92YXJzID0gYyhcXEhvc3BpdGFsXFwsIFxuICAgICAgICAgICAgICAgICAgIFxcQWdlXFwsIFxcR2VuZGVyXFwsIFxuICAgICAgICAgICAgICAgICAgIFxcVENfZmluYWxcXCwgXFxMRExfZmluYWxcXCwgXFxIRExfZmluYWxcXCwgXFxUR19maW5hbFxcLCBcbiAgICAgICAgICAgICAgICAgICBcXHN5c3RvbGljXFwsIFxcZGlhc3RvbGlcXCwgXFxHRlJfTURSRFxcLCBcXEJNSVxcLCBcbiAgICAgICAgICAgICAgICAgICBcXEtET1FJXFwsIFxcQk1JX1dIT1xcLCBcbiAgICAgICAgICAgICAgICAgICBcXFNtb2tlckN1cnJlbnRcXCwgXFxlQ2lnYXJldHRlc1xcLCBcXGVQYWNrWWVhcnNTbW9raW5nXFwsXG4gICAgICAgICAgICAgICAgICAgXFxEaWFiZXRlc1N0YXR1c1xcLCBcXEh5cGVydGVuc2lvbi5zZWxmcmVwb3J0XFwsIFxcSHlwZXJ0ZW5zaW9uLnNlbGZyZXBvcnRkcnVnXFwsIFxcSHlwZXJ0ZW5zaW9uLmNvbXBvc2l0ZVxcLCBcbiAgICAgICAgICAgICAgICAgICBcXEh5cGVydGVuc2lvbi5kcnVnc1xcLCBcXE1lZC5hbnRpY29hZ3VsYW50c1xcLCBcXE1lZC5hbGwuYW50aXBsYXRlbGV0XFwsIFxcTWVkLlN0YXRpbi5MTERcXCwgXG4gICAgICAgICAgICAgICAgICAgXFxTdHJva2VfRHhcXCwgXFxzeW1wdFxcLCBcXFN5bXB0b21zLjVHXFwsIFxccmVzdGVub3NcXCxcbiAgICAgICAgICAgICAgICAgICBcXEVQX2NvbXBvc2l0ZVxcLCBcXEVQX2NvbXBvc2l0ZV90aW1lXFwsXG4gICAgICAgICAgICAgICAgICAgXFxtYWNtZWFuMFxcLCBcXHNtY21lYW4wXFwsIFxcTWFjcm9waGFnZXMuYmluXFwsIFxcU01DLmJpblxcLCBcXG5ldXRyb3BoaWxzXFwsIFxcTWFzdF9jZWxsc19wbGFxdWVcXCwgXFx2ZXNzZWxfZGVuc2l0eV9hdmVyYWdlZFxcLFxuICAgICAgICAgICAgICAgICAgIFxcSVBILmJpblxcLCBcbiAgICAgICAgICAgICAgICAgICBcXENhbGMuYmluXFwsIFxcQ29sbGFnZW4uYmluXFwsIFxuICAgICAgICAgICAgICAgICAgIFxcRmF0LmJpbl8xMFxcLCBcXEZhdC5iaW5fNDBcXCwgXFxPdmVyYWxsUGxhcXVlUGhlbm90eXBlXFwsIFxcUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXhcXCxcbiAgICAgICAgICAgICAgICAgICBcXFNNQ19yYW5rTm9ybVxcLCBcXE1BQ19yYW5rTm9ybVxcLCBcXE5ldXRyb3BoaWxzX3JhbmtOb3JtXFwsIFxcTWFzdENlbGxzX3JhbmtOb3JtXFwsIFxcVmVzc2VsRGVuc2l0eV9yYW5rTm9ybVxcLFxuICAgICAgICAgICAgICAgICAgIFxcR1dBU1xcLCBcXENISVBcXCwgXFxQQ0FcXCxcbiAgICAgICAgICAgICAgICAgICBcXFBDU0s5X3BsYXNtYVxcLCBcXFBDU0s5X3BsYXNtYV9yYW5rTm9ybVxcKVxuXG5iYXNldGFibGVfYmluID0gYyhcXEdlbmRlclxcLCBcbiAgICAgICAgICAgICAgICAgIFxcS0RPUUlcXCwgXFxCTUlfV0hPXFwsIFxuICAgICAgICAgICAgICAgICAgXFxTbW9rZXJDdXJyZW50XFwsIFxuICAgICAgICAgICAgICAgICAgXFxEaWFiZXRlc1N0YXR1c1xcLCBcXEh5cGVydGVuc2lvbi5zZWxmcmVwb3J0XFwsIFxcSHlwZXJ0ZW5zaW9uLnNlbGZyZXBvcnRkcnVnXFwsIFxcSHlwZXJ0ZW5zaW9uLmNvbXBvc2l0ZVxcLCBcbiAgICAgICAgICAgICAgICAgIFxcSHlwZXJ0ZW5zaW9uLmRydWdzXFwsIFxcTWVkLmFudGljb2FndWxhbnRzXFwsIFxcTWVkLmFsbC5hbnRpcGxhdGVsZXRcXCwgXFxNZWQuU3RhdGluLkxMRFxcLCBcbiAgICAgICAgICAgICAgICAgIFxcU3Ryb2tlX0R4XFwsIFxcc3ltcHRcXCwgXFxTeW1wdG9tcy41R1xcLCBcXHJlc3Rlbm9zXFwsXG4gICAgICAgICAgICAgICAgICBcXEVQX2NvbXBvc2l0ZVxcLCBcXE1hY3JvcGhhZ2VzLmJpblxcLCBcXFNNQy5iaW5cXCxcbiAgICAgICAgICAgICAgICAgIFxcSVBILmJpblxcLCBcbiAgICAgICAgICAgICAgICAgIFxcQ2FsYy5iaW5cXCwgXFxDb2xsYWdlbi5iaW5cXCwgXG4gICAgICAgICAgICAgICAgICBcXEZhdC5iaW5fMTBcXCwgXFxGYXQuYmluXzQwXFwsIFxcT3ZlcmFsbFBsYXF1ZVBoZW5vdHlwZVxcLCBcXFBsYXF1ZV9WdWxuZXJhYmlsaXR5X0luZGV4XFwsXG4gICAgICAgICAgICAgICAgICBcXEdXQVNcXCwgXFxDSElQXFwsIFxcUENBXFwpXG5cbmJhc2V0YWJsZV9iaW5cbmBgYFxuYGBgIn0= -->

```r
```r
# Baseline table variables
basetable_vars = c(\Hospital\, 
                   \Age\, \Gender\, 
                   \TC_final\, \LDL_final\, \HDL_final\, \TG_final\, 
                   \systolic\, \diastoli\, \GFR_MDRD\, \BMI\, 
                   \KDOQI\, \BMI_WHO\, 
                   \SmokerCurrent\, \eCigarettes\, \ePackYearsSmoking\,
                   \DiabetesStatus\, \Hypertension.selfreport\, \Hypertension.selfreportdrug\, \Hypertension.composite\, 
                   \Hypertension.drugs\, \Med.anticoagulants\, \Med.all.antiplatelet\, \Med.Statin.LLD\, 
                   \Stroke_Dx\, \sympt\, \Symptoms.5G\, \restenos\,
                   \EP_composite\, \EP_composite_time\,
                   \macmean0\, \smcmean0\, \Macrophages.bin\, \SMC.bin\, \neutrophils\, \Mast_cells_plaque\, \vessel_density_averaged\,
                   \IPH.bin\, 
                   \Calc.bin\, \Collagen.bin\, 
                   \Fat.bin_10\, \Fat.bin_40\, \OverallPlaquePhenotype\, \Plaque_Vulnerability_Index\,
                   \SMC_rankNorm\, \MAC_rankNorm\, \Neutrophils_rankNorm\, \MastCells_rankNorm\, \VesselDensity_rankNorm\,
                   \GWAS\, \CHIP\, \PCA\,
                   \PCSK9_plasma\, \PCSK9_plasma_rankNorm\)

basetable_bin = c(\Gender\, 
                  \KDOQI\, \BMI_WHO\, 
                  \SmokerCurrent\, 
                  \DiabetesStatus\, \Hypertension.selfreport\, \Hypertension.selfreportdrug\, \Hypertension.composite\, 
                  \Hypertension.drugs\, \Med.anticoagulants\, \Med.all.antiplatelet\, \Med.Statin.LLD\, 
                  \Stroke_Dx\, \sympt\, \Symptoms.5G\, \restenos\,
                  \EP_composite\, \Macrophages.bin\, \SMC.bin\,
                  \IPH.bin\, 
                  \Calc.bin\, \Collagen.bin\, 
                  \Fat.bin_10\, \Fat.bin_40\, \OverallPlaquePhenotype\, \Plaque_Vulnerability_Index\,
                  \GWAS\, \CHIP\, \PCA\)

basetable_bin

<!-- rnb-source-end -->

<!-- rnb-output-begin eyJkYXRhIjoiIFsxXSBcXEdlbmRlclxcICAgICAgICAgICAgICAgICAgICAgIFxcS0RPUUlcXCAgICAgICAgICAgICAgICAgICAgICAgXFxCTUlfV0hPXFwgICAgICAgICAgICAgICAgICAgIFxuIFs0XSBcXFNtb2tlckN1cnJlbnRcXCAgICAgICAgICAgICAgIFxcRGlhYmV0ZXNTdGF0dXNcXCAgICAgICAgICAgICAgXFxIeXBlcnRlbnNpb24uc2VsZnJlcG9ydFxcICAgIFxuIFs3XSBcXEh5cGVydGVuc2lvbi5zZWxmcmVwb3J0ZHJ1Z1xcIFxcSHlwZXJ0ZW5zaW9uLmNvbXBvc2l0ZVxcICAgICAgXFxIeXBlcnRlbnNpb24uZHJ1Z3NcXCAgICAgICAgIFxuWzEwXSBcXE1lZC5hbnRpY29hZ3VsYW50c1xcICAgICAgICAgIFxcTWVkLmFsbC5hbnRpcGxhdGVsZXRcXCAgICAgICAgXFxNZWQuU3RhdGluLkxMRFxcICAgICAgICAgICAgIFxuWzEzXSBcXFN0cm9rZV9EeFxcICAgICAgICAgICAgICAgICAgIFxcc3ltcHRcXCAgICAgICAgICAgICAgICAgICAgICAgXFxTeW1wdG9tcy41R1xcICAgICAgICAgICAgICAgIFxuWzE2XSBcXHJlc3Rlbm9zXFwgICAgICAgICAgICAgICAgICAgIFxcRVBfY29tcG9zaXRlXFwgICAgICAgICAgICAgICAgXFxNYWNyb3BoYWdlcy5iaW5cXCAgICAgICAgICAgIFxuWzE5XSBcXFNNQy5iaW5cXCAgICAgICAgICAgICAgICAgICAgIFxcSVBILmJpblxcICAgICAgICAgICAgICAgICAgICAgXFxDYWxjLmJpblxcICAgICAgICAgICAgICAgICAgIFxuWzIyXSBcXENvbGxhZ2VuLmJpblxcICAgICAgICAgICAgICAgIFxcRmF0LmJpbl8xMFxcICAgICAgICAgICAgICAgICAgXFxGYXQuYmluXzQwXFwgICAgICAgICAgICAgICAgIFxuWzI1XSBcXE92ZXJhbGxQbGFxdWVQaGVub3R5cGVcXCAgICAgIFxcUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXhcXCAgXFxHV0FTXFwgICAgICAgICAgICAgICAgICAgICAgIFxuWzI4XSBcXENISVBcXCAgICAgICAgICAgICAgICAgICAgICAgIFxcUENBXFwgICAgICAgICAgICAgICAgICAgICAgICBcbiJ9 -->

[1]     _WHO 
[4]     .selfreport 
[7] .selfreportdrug .composite  .drugs 
[10] .anticoagulants  .all.antiplatelet  .Statin.LLD 
[13] _Dx    .5G 
[16]   _composite  .bin 
[19] .bin  .bin  .bin 
[22] .bin  .bin_10  .bin_40 
[25]   _Vulnerability_Index   
[28]    




<!-- rnb-output-end -->

<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuYmFzZXRhYmxlX2NvbiA9IGJhc2V0YWJsZV92YXJzWyFiYXNldGFibGVfdmFycyAlaW4lIGJhc2V0YWJsZV9iaW5dXG5iYXNldGFibGVfY29uXG5gYGBcbmBgYCJ9 -->

```r
```r
basetable_con = basetable_vars[!basetable_vars %in% basetable_bin]
basetable_con

<!-- rnb-source-end -->

<!-- rnb-output-begin eyJkYXRhIjoiIFsxXSBcXEhvc3BpdGFsXFwgICAgICAgICAgICAgICAgXFxBZ2VcXCAgICAgICAgICAgICAgICAgICAgIFxcVENfZmluYWxcXCAgICAgICAgICAgICAgICBcXExETF9maW5hbFxcICAgICAgICAgICAgICBcbiBbNV0gXFxIRExfZmluYWxcXCAgICAgICAgICAgICAgIFxcVEdfZmluYWxcXCAgICAgICAgICAgICAgICBcXHN5c3RvbGljXFwgICAgICAgICAgICAgICAgXFxkaWFzdG9saVxcICAgICAgICAgICAgICAgXG4gWzldIFxcR0ZSX01EUkRcXCAgICAgICAgICAgICAgICBcXEJNSVxcICAgICAgICAgICAgICAgICAgICAgXFxlQ2lnYXJldHRlc1xcICAgICAgICAgICAgIFxcZVBhY2tZZWFyc1Ntb2tpbmdcXCAgICAgIFxuWzEzXSBcXEVQX2NvbXBvc2l0ZV90aW1lXFwgICAgICAgXFxtYWNtZWFuMFxcICAgICAgICAgICAgICAgIFxcc21jbWVhbjBcXCAgICAgICAgICAgICAgICBcXG5ldXRyb3BoaWxzXFwgICAgICAgICAgICBcblsxN10gXFxNYXN0X2NlbGxzX3BsYXF1ZVxcICAgICAgIFxcdmVzc2VsX2RlbnNpdHlfYXZlcmFnZWRcXCBcXFNNQ19yYW5rTm9ybVxcICAgICAgICAgICAgXFxNQUNfcmFua05vcm1cXCAgICAgICAgICAgXG5bMjFdIFxcTmV1dHJvcGhpbHNfcmFua05vcm1cXCAgICBcXE1hc3RDZWxsc19yYW5rTm9ybVxcICAgICAgXFxWZXNzZWxEZW5zaXR5X3JhbmtOb3JtXFwgIFxcUENTSzlfcGxhc21hXFwgICAgICAgICAgIFxuWzI1XSBcXFBDU0s5X3BsYXNtYV9yYW5rTm9ybVxcICBcbiJ9 -->

[1]     _final  _final 
[5] _final  _final     
[9] _MDRD       
[13] _composite_time       
[17] _cells_plaque  _density_averaged _rankNorm  _rankNorm 
[21] _rankNorm  _rankNorm  _rankNorm  _plasma 
[25] _plasma_rankNorm 




<!-- rnb-output-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->


All Athero-Express Genomics Study data (n = 2,011), compared to the *remaining*, \_un_genotyped Athero-Express Biobank
Study.


<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuY2F0KFwiXFxuPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcblwiKVxuY2F0KFwiRElTUExBWSBCQVNFTElORSBUQUJMRVxcblwiKVxuXG5BRUdTc2VsZWN0LnRhYmxlT25lID0gcHJpbnQoQ3JlYXRlVGFibGVPbmUodmFycyA9IGJhc2V0YWJsZV92YXJzLCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBmYWN0b3JWYXJzID0gYmFzZXRhYmxlX2JpbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyYXRhID0gXCJHV0FTXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBBRUdTc2VsZWN0LCBpbmNsdWRlTkEgPSBUUlVFKSwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgIG5vbm5vcm1hbCA9IGMoKSwgbWlzc2luZyA9IFRSVUUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHF1b3RlID0gRkFMU0UsIG5vU3BhY2VzID0gRkFMU0UsIHNob3dBbGxMZXZlbHMgPSBUUlVFLCBleHBsYWluID0gVFJVRSwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdCA9IFwicGZcIiwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnREaWdpdHMgPSAzKVssMTo2XVxuYGBgIn0= -->

```r
cat("\n===========================================================================================\n")
cat("DISPLAY BASELINE TABLE\n")

AEGSselect.tableOne = print(CreateTableOne(vars = basetable_vars, 
                                         # factorVars = basetable_bin,
                                         strata = "GWAS",
                                         data = AEGSselect, includeNA = TRUE), 
                          nonnormal = c(), missing = TRUE,
                          quote = FALSE, noSpaces = FALSE, showAllLevels = TRUE, explain = TRUE, 
                          format = "pf", 
                          contDigits = 3)[,1:6]

Baseline of the valid, CEA and genotyped data.

AEGSselect.CEA.tableOne = print(CreateTableOne(vars = basetable_vars, 
                                         # factorVars = basetable_bin,
                                         strata = "Gender",
                                         data = AEGSselect.CEA, includeNA = TRUE), 
                          nonnormal = c(), missing = TRUE,
                          quote = FALSE, noSpaces = FALSE, showAllLevels = TRUE, explain = TRUE, 
                          format = "pf", 
                          contDigits = 3)[,1:6]

Baseline writing

Let’s save the baseline characteristics of the Athero-Express Genomics Study.

# Write basetable
require(openxlsx)

write.xlsx(file = paste0(BASELINE_loc, "/",Today,".",PROJECTNAME,".AEGS.BaselineTable.xlsx"), 
           format(as.data.frame(AEGSselect.tableOne), digits = 5, scientific = FALSE),
           rowNames = TRUE, 
           colNames = TRUE, 
           sheetName = "AEGS_Base_AEDB", overwrite = TRUE)

write.xlsx(file = paste0(BASELINE_loc, "/",Today,".",PROJECTNAME,".AEGS.CEA.BaselineTable.xlsx"), 
           format(as.data.frame(AEGSselect.CEA.tableOne), digits = 5, scientific = FALSE),
           rowNames = TRUE, 
           colNames = TRUE, 
           sheetName = "AEGS_Base_CEA_sex", overwrite = TRUE)

SampleLists

Autosomal data.

We are ready to make a sampleList for use with the imputed data.

require(openxlsx)

temp <- subset(AEGS,
               GWAS == "genotyped",
               select = c("ID_1", "ID_2", "UPID", "STUDY_NUMBER", # ID_2 is the order of samples!
                          "QC2018_FINAL", "QC2018_FILTER", "OriginalOrder_postMichImp_QC",
                          "AEGS_type", "CHIP", "STUDY_TYPE", "SAMPLE_TYPE", "PCA",
                          "PC1", "PC2", "PC3", "PC4", "PC5",
                          "PC6", "PC7", "PC8", "PC9", "PC10",
                          "Sex", "Age", "ORyear", 
                          "Calc.bin", "Collagen.bin", 
                          "Fat.bin_10", "Fat.bin_40", "IPH.bin", 
                          "SMC_rankNorm", "MAC_rankNorm", "Neutrophils_rankNorm", "MastCells_rankNorm", "VesselDensity_rankNorm",
                          "Plaque_Vulnerability_Index",
                          "PCSK9_plasma", "PCSK9_plasma_rankNorm")) # Select some phenotype of interest
dim(temp)
[1] 2124   38
# Fix things
attach(temp)

temp[,"Calcification"] <- NA
temp$Calcification[Calc.bin == "no/minor"] <- "control"
temp$Calcification[Calc.bin == "moderate/heavy"] <- "case"

temp[,"Collagen"] <- NA
temp$Collagen[Collagen.bin == "no/minor"] <- "control"
temp$Collagen[Collagen.bin == "moderate/heavy"] <- "case"

temp[,"Fat10"] <- NA
temp$Fat10[Fat.bin_10 == "<10%"] <- "control"
temp$Fat10[Fat.bin_10 == ">10%"] <- "case"

temp[,"Fat40"] <- NA
temp$Fat40[Fat.bin_40 == "<40%"] <- "control"
temp$Fat40[Fat.bin_40 == ">40%"] <- "case"

temp[,"IPH"] <- NA
temp$IPH[IPH.bin == "no"] <- "control"
temp$IPH[IPH.bin == "yes"] <- "case"

temp[,"PVI"] <- NA
temp$PVI[Plaque_Vulnerability_Index == "0"] <- "PVI_cat0"
temp$PVI[Plaque_Vulnerability_Index == "1"] <- "PVI_cat1"
temp$PVI[Plaque_Vulnerability_Index == "2"] <- "PVI_cat2"
temp$PVI[Plaque_Vulnerability_Index == "3"] <- "PVI_cat3"
temp$PVI[Plaque_Vulnerability_Index == "4"] <- "PVI_cat4"
temp$PVI[Plaque_Vulnerability_Index == "5"] <- "PVI_cat5"

temp$Plaque_Vulnerability_Index <- temp$PVI
temp$PVI <- NULL

detach(temp)

# Making selection variable
attach(temp)
temp[,"SELECTION"] <- "not_selected"
temp$SELECTION[(QC2018_FILTER=="passed" | QC2018_FILTER=="family_keep") & (STUDY_TYPE=="CEA" & PCA=="EUR")] <- "selected"
detach(temp)
table(temp$SELECTION, temp$QC2018_FILTER)
              
               family_discard family_keep issue passed
  not_selected             23           0    41    152
  selected                  0          21     0   1887
table(temp$SELECTION, temp$STUDY_TYPE)
              
                CEA  FEA Other
  not_selected   94  109    12
  selected     1908    0     0
table(temp$SELECTION, temp$PCA)
              
                EUR nonEUR
  not_selected  167     45
  selected     1908      0
table(temp$Plaque_Vulnerability_Index)

PVI_cat0 PVI_cat1 PVI_cat2 PVI_cat3 PVI_cat4 PVI_cat5 
     453      348      422      478      221       84 
# Check https://www.well.ox.ac.uk/~gav/snptest/#multinomial_tests for details on multiple categories testing in SNPTEST

AEGS123_sample.list <- temp[order(temp$OriginalOrder_postMichImp_QC),]

AEGS123_sample.list$missing <- 0

sample_file_aegs <- dplyr::select(AEGS123_sample.list,
                                  ID_1, ID_2, missing, # ID_2 is the order of samples - that way we always know what the order should be
                                  UPID, STUDY_NUMBER, 
                                  QC2018_FINAL, QC2018_FILTER, SELECTION,
                                  AEGS_type, CHIP, STUDY_TYPE, SAMPLE_TYPE, PCA,
                                  PC1, PC2, PC3, PC4, PC5, PC6, PC7, PC8, PC9, PC10,
                                  Sex, Age, ORyear, 
                                  Calcification, Collagen, 
                                  Fat10, Fat40, IPH, 
                                  SMC_rankNorm, MAC_rankNorm, Neutrophils_rankNorm, MastCells_rankNorm, VesselDensity_rankNorm,
                                  Plaque_Vulnerability_Index,
                                  PCSK9_plasma, PCSK9_plasma_rankNorm)  %>%
  mutate_if(is.numeric, as.character) %>%
  mutate(SAMPLE_TYPE = gsub(' ', '_', SAMPLE_TYPE)) %>%
  add_row(.before = 1, 
          ID_1 = "0", ID_2 = "0", missing = "0", 
          UPID = "D", STUDY_NUMBER = "C",
          QC2018_FINAL = "D", QC2018_FILTER = "D", SELECTION = "D",
          AEGS_type = "D", CHIP = "D", STUDY_TYPE = "D", SAMPLE_TYPE = "D", PCA = "D",
          PC1 = "C", PC2 = "C", PC3 = "C", PC4 = "C", PC5 = "C", PC6 = "C", PC7 = "C", PC8 = "C", PC9 = "C", PC10 = "C",
          Sex = "D", Age = "C", ORyear = "C", 
          Calcification = "B", Collagen = "B", 
          Fat10 = "B", Fat40 = "B", IPH = "B", 
          SMC_rankNorm = "P", MAC_rankNorm = "P", Neutrophils_rankNorm = "P", MastCells_rankNorm = "P", VesselDensity_rankNorm = "P",
          Plaque_Vulnerability_Index = "D",
          PCSK9_plasma = "P", PCSK9_plasma_rankNorm = "P") %>% ## identifiers: index for these is 1, and all base variables have 0 as identifier
  print()
dim(sample_file_aegs)
[1] 2125   39
fwrite(sample_file_aegs,
       file = paste0(SNP_loc, "/",Today,".",PROJECTNAME,".AEGS123.sample"),
       na = "NA", sep = "\t", quote = FALSE,
       row.names = FALSE, col.names = TRUE,
       showProgress = TRUE, verbose = TRUE)
This installation of data.table has not been compiled with OpenMP support.
  omp_get_num_procs()            1
  R_DATATABLE_NUM_PROCS_PERCENT  unset (default 50)
  R_DATATABLE_NUM_THREADS        unset
  R_DATATABLE_THROTTLE           unset (default 1024)
  omp_get_thread_limit()         1
  omp_get_max_threads()          1
  OMP_THREAD_LIMIT               unset
  OMP_NUM_THREADS                1
  RestoreAfterFork               true
  data.table is using 1 threads with throttle==1024. See ?setDTthreads.
No list columns are present. Setting sep2='' otherwise quote='auto' would quote fields containing sep2.
Column writers: 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 
args.doRowNames=0 args.rowNames=0 doQuote=0 args.nrow=2125 args.ncol=39 eolLen=1
maxLineLen=924. Found in 0.000s
Writing bom (false), yaml (0 characters) and column names (true) ... done in 0.001s
Writing 2125 rows in 1 batches of 2125 rows (each buffer size 8MB, showProgress=1, nth=1)
require(DT)
DT::datatable(sample_file_aegs, caption = "AEGS: final sample list of genotyped AE patients after quality control.", rownames = FALSE)
Warning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.htmlWarning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.html
rm(temp, temp2, temp3)
Warning: object 'temp2' not foundWarning: object 'temp3' not found

Females only

This is the selection for females only.

require(openxlsx)

temp <- subset(AEGS,
               GWAS == "genotyped",
               select = c("ID_1", "ID_2", "UPID", "STUDY_NUMBER", # ID_2 is the order of samples!
                          "QC2018_FINAL", "QC2018_FILTER", "OriginalOrder_postMichImp_QC",
                          "AEGS_type", "CHIP", "STUDY_TYPE", "SAMPLE_TYPE", "PCA",
                          "PC1", "PC2", "PC3", "PC4", "PC5",
                          "PC6", "PC7", "PC8", "PC9", "PC10",
                          "Sex", "Age", "ORyear", 
                          "BMI",
                          "Calc.bin", "Collagen.bin", 
                          "Fat.bin_10", "Fat.bin_40", "IPH.bin", 
                          "SMC_rankNorm", "MAC_rankNorm", "Neutrophils_rankNorm", "MastCells_rankNorm", "VesselDensity_rankNorm", 
                          "OverallPlaquePhenotype", "Plaque_Vulnerability_Index",
                          "PCSK9_plasma", "PCSK9_plasma_rankNorm")) # Select some phenotype of interest
dim(temp)
[1] 2124   40
# Fix things
attach(temp)

temp[,"Calcification"] <- NA
temp$Calcification[Calc.bin == "no/minor"] <- "control"
temp$Calcification[Calc.bin == "moderate/heavy"] <- "case"

temp[,"Collagen"] <- NA
temp$Collagen[Collagen.bin == "no/minor"] <- "control"
temp$Collagen[Collagen.bin == "moderate/heavy"] <- "case"

temp[,"Fat10"] <- NA
temp$Fat10[Fat.bin_10 == "<10%"] <- "control"
temp$Fat10[Fat.bin_10 == ">10%"] <- "case"

temp[,"Fat40"] <- NA
temp$Fat40[Fat.bin_40 == "<40%"] <- "control"
temp$Fat40[Fat.bin_40 == ">40%"] <- "case"

temp[,"IPH"] <- NA
temp$IPH[IPH.bin == "no"] <- "control"
temp$IPH[IPH.bin == "yes"] <- "case"

temp[,"PVI"] <- NA
temp$PVI[Plaque_Vulnerability_Index == "0"] <- "PVI_cat0"
temp$PVI[Plaque_Vulnerability_Index == "1"] <- "PVI_cat1"
temp$PVI[Plaque_Vulnerability_Index == "2"] <- "PVI_cat2"
temp$PVI[Plaque_Vulnerability_Index == "3"] <- "PVI_cat3"
temp$PVI[Plaque_Vulnerability_Index == "4"] <- "PVI_cat4"
temp$PVI[Plaque_Vulnerability_Index == "5"] <- "PVI_cat5"

temp$Plaque_Vulnerability_Index <- temp$PVI
temp$PVI <- NULL

detach(temp)

# Making selection variable
attach(temp)
temp[,"SELECTION"] <- "not_selected"
temp$SELECTION[(QC2018_FILTER=="passed" | QC2018_FILTER=="family_keep") & (STUDY_TYPE=="CEA" & PCA=="EUR") & Sex=="F"] <- "selected"
detach(temp)
table(temp$SELECTION, temp$QC2018_FILTER)
              
               family_discard family_keep issue passed
  not_selected             23          15    41   1427
  selected                  0           6     0    612
table(temp$SELECTION, temp$STUDY_TYPE)
              
                CEA  FEA Other
  not_selected 1384  109    12
  selected      618    0     0
table(temp$SELECTION, temp$PCA)
              
                EUR nonEUR
  not_selected 1457     45
  selected      618      0
AEGS123_sample.list <- temp[order(temp$OriginalOrder_postMichImp_QC),]

AEGS123_sample.list$missing <- 0

sample_file_aegsF <- dplyr::select(AEGS123_sample.list,
                                  ID_1, ID_2, missing, # ID_2 is the order of samples - that way we always know what the order should be
                                  UPID, STUDY_NUMBER, 
                                  QC2018_FINAL, QC2018_FILTER, SELECTION,
                                  AEGS_type, CHIP, STUDY_TYPE, SAMPLE_TYPE, PCA,
                                  PC1, PC2, PC3, PC4, PC5, PC6, PC7, PC8, PC9, PC10,
                                  Sex, Age, ORyear, 
                                  Calcification, Collagen, 
                                  Fat10, Fat40, IPH, 
                                  SMC_rankNorm, MAC_rankNorm, Neutrophils_rankNorm, MastCells_rankNorm, VesselDensity_rankNorm,
                                  Plaque_Vulnerability_Index,
                                  PCSK9_plasma, PCSK9_plasma_rankNorm)  %>%
  mutate_if(is.numeric, as.character) %>%
  mutate(SAMPLE_TYPE = gsub(' ', '_', SAMPLE_TYPE)) %>%
  add_row(.before = 1, 
          ID_1 = "0", ID_2 = "0", missing = "0", 
          UPID = "D", STUDY_NUMBER = "C",
          QC2018_FINAL = "D", QC2018_FILTER = "D", SELECTION = "D",
          AEGS_type = "D", CHIP = "D", STUDY_TYPE = "D", SAMPLE_TYPE = "D", PCA = "D",
          PC1 = "C", PC2 = "C", PC3 = "C", PC4 = "C", PC5 = "C", PC6 = "C", PC7 = "C", PC8 = "C", PC9 = "C", PC10 = "C",
          Sex = "D", Age = "C", ORyear = "C", 
          Calcification = "B", Collagen = "B", 
          Fat10 = "B", Fat40 = "B", IPH = "B", 
          SMC_rankNorm = "P", MAC_rankNorm = "P", Neutrophils_rankNorm = "P", MastCells_rankNorm = "P", VesselDensity_rankNorm = "P",
          Plaque_Vulnerability_Index = "D",
          PCSK9_plasma = "P", PCSK9_plasma_rankNorm = "P") %>% ## identifiers: index for these is 1, and all base variables have 0 as identifier
  print()
dim(sample_file_aegsF)
[1] 2125   39
fwrite(sample_file_aegsF,
       file = paste0(SNP_loc, "/",Today,".",PROJECTNAME,".AEGS123.females.sample"),
       na = "NA", sep = "\t", quote = FALSE,
       row.names = FALSE, col.names = TRUE,
       showProgress = TRUE, verbose = TRUE)
This installation of data.table has not been compiled with OpenMP support.
  omp_get_num_procs()            1
  R_DATATABLE_NUM_PROCS_PERCENT  unset (default 50)
  R_DATATABLE_NUM_THREADS        unset
  R_DATATABLE_THROTTLE           unset (default 1024)
  omp_get_thread_limit()         1
  omp_get_max_threads()          1
  OMP_THREAD_LIMIT               unset
  OMP_NUM_THREADS                1
  RestoreAfterFork               true
  data.table is using 1 threads with throttle==1024. See ?setDTthreads.
No list columns are present. Setting sep2='' otherwise quote='auto' would quote fields containing sep2.
Column writers: 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 
args.doRowNames=0 args.rowNames=0 doQuote=0 args.nrow=2125 args.ncol=39 eolLen=1
maxLineLen=924. Found in 0.000s
Writing bom (false), yaml (0 characters) and column names (true) ... done in 0.001s
Writing 2125 rows in 1 batches of 2125 rows (each buffer size 8MB, showProgress=1, nth=1)
require(DT)
DT::datatable(sample_file_aegsF, caption = "AEGS: final sample list of genotyped AE patients after quality control.", rownames = FALSE)
Warning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.htmlWarning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.html
rm(temp)

Males only

This is the selection for males only.

require(openxlsx)

temp <- subset(AEGS,
               GWAS == "genotyped",
               select = c("ID_1", "ID_2", "UPID", "STUDY_NUMBER", # ID_2 is the order of samples!
                          "QC2018_FINAL", "QC2018_FILTER", "OriginalOrder_postMichImp_QC",
                          "AEGS_type", "CHIP", "STUDY_TYPE", "SAMPLE_TYPE", "PCA",
                          "PC1", "PC2", "PC3", "PC4", "PC5",
                          "PC6", "PC7", "PC8", "PC9", "PC10",
                          "Sex", "Age", "ORyear", 
                          "BMI",
                          "Calc.bin", "Collagen.bin", 
                          "Fat.bin_10", "Fat.bin_40", "IPH.bin", 
                          "SMC_rankNorm", "MAC_rankNorm", "Neutrophils_rankNorm", "MastCells_rankNorm", "VesselDensity_rankNorm", 
                          "OverallPlaquePhenotype", "Plaque_Vulnerability_Index",
                          "PCSK9_plasma", "PCSK9_plasma_rankNorm")) # Select some phenotype of interest
dim(temp)
[1] 2124   40
# Fix things
attach(temp)

temp[,"Calcification"] <- NA
temp$Calcification[Calc.bin == "no/minor"] <- "control"
temp$Calcification[Calc.bin == "moderate/heavy"] <- "case"

temp[,"Collagen"] <- NA
temp$Collagen[Collagen.bin == "no/minor"] <- "control"
temp$Collagen[Collagen.bin == "moderate/heavy"] <- "case"

temp[,"Fat10"] <- NA
temp$Fat10[Fat.bin_10 == "<10%"] <- "control"
temp$Fat10[Fat.bin_10 == ">10%"] <- "case"

temp[,"Fat40"] <- NA
temp$Fat40[Fat.bin_40 == "<40%"] <- "control"
temp$Fat40[Fat.bin_40 == ">40%"] <- "case"

temp[,"IPH"] <- NA
temp$IPH[IPH.bin == "no"] <- "control"
temp$IPH[IPH.bin == "yes"] <- "case"

temp[,"PVI"] <- NA
temp$PVI[Plaque_Vulnerability_Index == "0"] <- "PVI_cat0"
temp$PVI[Plaque_Vulnerability_Index == "1"] <- "PVI_cat1"
temp$PVI[Plaque_Vulnerability_Index == "2"] <- "PVI_cat2"
temp$PVI[Plaque_Vulnerability_Index == "3"] <- "PVI_cat3"
temp$PVI[Plaque_Vulnerability_Index == "4"] <- "PVI_cat4"
temp$PVI[Plaque_Vulnerability_Index == "5"] <- "PVI_cat5"

temp$Plaque_Vulnerability_Index <- temp$PVI
temp$PVI <- NULL

detach(temp)

# Making selection variable
attach(temp)
temp[,"SELECTION"] <- "not_selected"
temp$SELECTION[(QC2018_FILTER=="passed" | QC2018_FILTER=="family_keep") & (STUDY_TYPE=="CEA" & PCA=="EUR") & Sex=="M"] <- "selected"
detach(temp)
table(temp$SELECTION, temp$QC2018_FILTER)
              
               family_discard family_keep issue passed
  not_selected             23           6    41    764
  selected                  0          15     0   1275
table(temp$SELECTION, temp$STUDY_TYPE)
              
                CEA  FEA Other
  not_selected  712  109    12
  selected     1290    0     0
table(temp$SELECTION, temp$PCA)
              
                EUR nonEUR
  not_selected  785     45
  selected     1290      0
AEGS123_sample.list <- temp[order(temp$OriginalOrder_postMichImp_QC),]

AEGS123_sample.list$missing <- 0

sample_file_aegsM <- dplyr::select(AEGS123_sample.list,
                                  ID_1, ID_2, missing, # ID_2 is the order of samples - that way we always know what the order should be
                                  UPID, STUDY_NUMBER, 
                                  QC2018_FINAL, QC2018_FILTER, SELECTION,
                                  AEGS_type, CHIP, STUDY_TYPE, SAMPLE_TYPE, PCA,
                                  PC1, PC2, PC3, PC4, PC5, PC6, PC7, PC8, PC9, PC10,
                                  Sex, Age, ORyear, 
                                  Calcification, Collagen, 
                                  Fat10, Fat40, IPH, 
                                  SMC_rankNorm, MAC_rankNorm, Neutrophils_rankNorm, MastCells_rankNorm, VesselDensity_rankNorm,
                                  Plaque_Vulnerability_Index,
                                  PCSK9_plasma, PCSK9_plasma_rankNorm)  %>%
  mutate_if(is.numeric, as.character) %>%
  mutate(SAMPLE_TYPE = gsub(' ', '_', SAMPLE_TYPE)) %>%
  add_row(.before = 1, 
          ID_1 = "0", ID_2 = "0", missing = "0", 
          UPID = "D", STUDY_NUMBER = "C",
          QC2018_FINAL = "D", QC2018_FILTER = "D", SELECTION = "D",
          AEGS_type = "D", CHIP = "D", STUDY_TYPE = "D", SAMPLE_TYPE = "D", PCA = "D",
          PC1 = "C", PC2 = "C", PC3 = "C", PC4 = "C", PC5 = "C", PC6 = "C", PC7 = "C", PC8 = "C", PC9 = "C", PC10 = "C",
          Sex = "D", Age = "C", ORyear = "C", 
          Calcification = "B", Collagen = "B", 
          Fat10 = "B", Fat40 = "B", IPH = "B", 
          SMC_rankNorm = "P", MAC_rankNorm = "P", Neutrophils_rankNorm = "P", MastCells_rankNorm = "P", VesselDensity_rankNorm = "P",
          Plaque_Vulnerability_Index = "D",
          PCSK9_plasma = "P", PCSK9_plasma_rankNorm = "P") %>% ## identifiers: index for these is 1, and all base variables have 0 as identifier
  print()
dim(sample_file_aegsM)
[1] 2125   39
fwrite(sample_file_aegsM,
       file = paste0(SNP_loc, "/",Today,".",PROJECTNAME,".AEGS123.males.sample"),
       na = "NA", sep = "\t", quote = FALSE,
       row.names = FALSE, col.names = TRUE,
       showProgress = TRUE, verbose = TRUE)
This installation of data.table has not been compiled with OpenMP support.
  omp_get_num_procs()            1
  R_DATATABLE_NUM_PROCS_PERCENT  unset (default 50)
  R_DATATABLE_NUM_THREADS        unset
  R_DATATABLE_THROTTLE           unset (default 1024)
  omp_get_thread_limit()         1
  omp_get_max_threads()          1
  OMP_THREAD_LIMIT               unset
  OMP_NUM_THREADS                1
  RestoreAfterFork               true
  data.table is using 1 threads with throttle==1024. See ?setDTthreads.
No list columns are present. Setting sep2='' otherwise quote='auto' would quote fields containing sep2.
Column writers: 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 
args.doRowNames=0 args.rowNames=0 doQuote=0 args.nrow=2125 args.ncol=39 eolLen=1
maxLineLen=924. Found in 0.000s
Writing bom (false), yaml (0 characters) and column names (true) ... done in 0.001s
Writing 2125 rows in 1 batches of 2125 rows (each buffer size 8MB, showProgress=1, nth=1)
require(DT)
DT::datatable(sample_file_aegsM, caption = "AEGS: final sample list of genotyped AE patients after quality control.", rownames = FALSE)
Warning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.htmlWarning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.html
rm(temp)

X-chromosome data

The X-chromosome data is taken from previously imputed data based on 1000G phase 3 (version 5) and GoNL5. For some reason, imputing on the Michigan Imputation Server was not successful (ACTION point).

Here we load in the sample files for the three datasets of the X chromosomal data. We should:

  • filter out samples that did not pass quality control, ending up with 2,124 sample
  • re-order the data to fit the other autosomal data.

AEGS123_chrX <- fread(paste0(MICHIMP_loc, "/_chr23_1kg_gonl5/aegs.raw.1kg_gonl5.chr23.mappings.txt"))
names(AEGS123_chrX)[names(AEGS123_chrX) == "ID_1"] <- "SampleID_postImpChrX"

AEGS123_AllChr <- merge(AEGS123_chrX, sample_file_aegs, by.x = "SampleID_postMichImp", by.y = "ID_1", 
                        all.x = TRUE, 
                        sort = FALSE)

names(AEGS123_AllChr)[names(AEGS123_AllChr) == "ID_2.y"] <- "ID_2"
names(AEGS123_AllChr)[names(AEGS123_AllChr) == "STUDY_TYPE.y"] <- "STUDY_TYPE"
names(AEGS123_AllChr)[names(AEGS123_AllChr) == "SampleID_postMichImp"] <- "ID_1"
AEGS123_AllChr$missing.x <- NULL
AEGS123_AllChr$missing.y <- NULL
AEGS123_AllChr$STUDY_TYPE.x <- NULL
AEGS123_AllChr$ID_2.x <- NULL

dim(AEGS123_AllChr)
[1] 2176   44
str(AEGS123_AllChr)
Classes ‘data.table’ and 'data.frame':  2176 obs. of  44 variables:
 $ ID_1                      : chr  "0" "UPID00126-UPID00126-A318-0034" "UPID01799-UPID01799-A318-0492" "UPID01890-UPID01890-A318-0151" ...
 $ SampleID_postImpChrX      : chr  "0" "UPID00126-UPID00126-A318-0034" "UPID01799-UPID01799-A318-0492" "UPID01890-UPID01890-A318-0151" ...
 $ MappingID                 : chr  "0" "UPID00126-UPID00126-A318-0034" "UPID01799-UPID01799-A318-0492" "UPID01890-UPID01890-A318-0151" ...
 $ FID_forQC                 : chr  "0" "UPID00126" "UPID01799" "UPID01890" ...
 $ IID_forQC                 : chr  "0" "UPID00126-UPID00126-A318-0034" "UPID01799-UPID01799-A318-0492" "UPID01890-UPID01890-A318-0151" ...
 $ SampleID_postQC           : chr  "0" "UPID00126-UPID00126-A318-0034" "UPID01799-UPID01799-A318-0492" "UPID01890-UPID01890-A318-0151" ...
 $ ChrX_Order                : int  0 1 2 NA 3 4 5 6 NA 7 ...
 $ ID_2                      : chr  "0" "22" "325" NA ...
 $ UPID                      : chr  "D" NA NA NA ...
 $ STUDY_NUMBER              : chr  "C" "901" "1164" NA ...
 $ QC2018_FINAL              : chr  "D" NA NA NA ...
 $ QC2018_FILTER             : chr  "D" "passed" "passed" NA ...
 $ SELECTION                 : chr  "D" "selected" "selected" NA ...
 $ AEGS_type                 : chr  "D" "AEGS1" "AEGS1" NA ...
 $ CHIP                      : chr  "D" "AffySNP5" "AffySNP5" NA ...
 $ STUDY_TYPE                : chr  "D" "CEA" "CEA" NA ...
 $ SAMPLE_TYPE               : chr  "D" "plaque" "plaque" NA ...
 $ PCA                       : chr  "D" "EUR" "EUR" NA ...
 $ PC1                       : chr  "C" "-0.0316" "-0.0131" NA ...
 $ PC2                       : chr  "C" "0.0161" "-0.0069" NA ...
 $ PC3                       : chr  "C" "-0.01" "0.0383" NA ...
 $ PC4                       : chr  "C" "-0.0131" "-0.005" NA ...
 $ PC5                       : chr  "C" "0.0059" "0.0078" NA ...
 $ PC6                       : chr  "C" "-0.0283" "0.0243" NA ...
 $ PC7                       : chr  "C" "-2e-04" "-0.018" NA ...
 $ PC8                       : chr  "C" "0.0033" "0.0022" NA ...
 $ PC9                       : chr  "C" "-0.0317" "-0.0154" NA ...
 $ PC10                      : chr  "C" "-0.0054" "0.007" NA ...
 $ Sex                       : chr  "D" "F" "M" NA ...
 $ Age                       : chr  "C" NA NA NA ...
 $ ORyear                    : chr  "C" NA NA NA ...
 $ Calcification             : chr  "B" NA NA NA ...
 $ Collagen                  : chr  "B" NA NA NA ...
 $ Fat10                     : chr  "B" NA NA NA ...
 $ Fat40                     : chr  "B" NA NA NA ...
 $ IPH                       : chr  "B" NA NA NA ...
 $ SMC_rankNorm              : chr  "P" NA NA NA ...
 $ MAC_rankNorm              : chr  "P" NA NA NA ...
 $ Neutrophils_rankNorm      : chr  "P" NA NA NA ...
 $ MastCells_rankNorm        : chr  "P" NA NA NA ...
 $ VesselDensity_rankNorm    : chr  "P" NA NA NA ...
 $ Plaque_Vulnerability_Index: chr  "D" NA NA NA ...
 $ PCSK9_plasma              : chr  "P" NA NA NA ...
 $ PCSK9_plasma_rankNorm     : chr  "P" NA NA NA ...
 - attr(*, ".internal.selfref")=<externalptr> 

This seems fine, let’s filter; we can use this file to filter the genetic data. And we create another file to re-order the data.


AEGS123_AllChrQC <- subset(AEGS123_AllChr,
               !is.na(QC2018_FILTER),
               select = c("ID_1", "ID_2", "UPID", "STUDY_NUMBER", "SampleID_postImpChrX",
                          "QC2018_FINAL", "QC2018_FILTER", "SELECTION",
                          "AEGS_type", "CHIP", "STUDY_TYPE", "SAMPLE_TYPE",
                          "PC1", "PC2", "PC3", "PC4", "PC5",
                          "PC6", "PC7", "PC8", "PC9", "PC10",
                          "Sex", "Age", "ORyear", 
                          "Calcification", "Collagen", 
                          "Fat10", "Fat40", "IPH", 
                          "SMC_rankNorm", "MAC_rankNorm", "Neutrophils_rankNorm", "MastCells_rankNorm", "VesselDensity_rankNorm",
                          "Plaque_Vulnerability_Index",
                          "PCSK9_plasma", "PCSK9_plasma_rankNorm"))

AEGS123_AllChrQC_reorder <-AEGS123_AllChrQC[order(AEGS123_AllChrQC$ID_2),] # remember: ID_2 is the order of samples

AEGS123_AllChrQC_filtered <- subset(AEGS123_AllChr,
               is.na(QC2018_FILTER),
               select = c("ID_1", "ID_2", "UPID", "STUDY_NUMBER", "SampleID_postImpChrX",
                          "QC2018_FINAL", "QC2018_FILTER", "SELECTION",
                          "AEGS_type", "CHIP", "STUDY_TYPE", "SAMPLE_TYPE",
                          "PC1", "PC2", "PC3", "PC4", "PC5",
                          "PC6", "PC7", "PC8", "PC9", "PC10",
                          "Sex", "Age", "ORyear", 
                          "Calcification", "Collagen", 
                          "Fat10", "Fat40", "IPH", 
                          "SMC_rankNorm", "MAC_rankNorm", "Neutrophils_rankNorm", "MastCells_rankNorm", "VesselDensity_rankNorm",
                          "Plaque_Vulnerability_Index",
                          "PCSK9_plasma", "PCSK9_plasma_rankNorm"))

fwrite(AEGS123_AllChrQC_reorder,
       file = paste0(SNP_loc, "/",Today,".",PROJECTNAME,".AEGS123.chrX.sample"),
       na = "NA", sep = "\t", quote = FALSE,
       row.names = FALSE, col.names = TRUE,
       showProgress = TRUE, verbose = TRUE)
This installation of data.table has not been compiled with OpenMP support.
  omp_get_num_procs()            1
  R_DATATABLE_NUM_PROCS_PERCENT  unset (default 50)
  R_DATATABLE_NUM_THREADS        unset
  R_DATATABLE_THROTTLE           unset (default 1024)
  omp_get_thread_limit()         1
  omp_get_max_threads()          1
  OMP_THREAD_LIMIT               unset
  OMP_NUM_THREADS                1
  RestoreAfterFork               true
  data.table is using 1 threads with throttle==1024. See ?setDTthreads.
No list columns are present. Setting sep2='' otherwise quote='auto' would quote fields containing sep2.
Column writers: 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 
args.doRowNames=0 args.rowNames=0 doQuote=0 args.nrow=2013 args.ncol=38 eolLen=1
maxLineLen=991. Found in 0.000s
Writing bom (false), yaml (0 characters) and column names (true) ... done in 0.001s
Writing 2013 rows in 1 batches of 2013 rows (each buffer size 8MB, showProgress=1, nth=1)
require(DT)
DT::datatable(AEGS123_AllChrQC, caption = "AEGS: final sample list of genotyped AE patients after quality control (chromosome X).", rownames = FALSE)
Warning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.htmlWarning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.html

GWASToolKit preparation

VariantLists: top SNPs

Here we create a variantlist.txt file used by GWASToolKit for analysis.These are the variants with LD r2 => 0.6 around each of the 15 top SNPs associated with CAC.

variant_list

temp <- subset(variant_list, select = c("VariantID", "Chr", "BP"))

fwrite(temp,
       file = paste0(SNP_loc, "/variantlist.txt"),
       na = "NA", sep = "\t", quote = FALSE,
       row.names = FALSE, col.names = FALSE,
       showProgress = TRUE, verbose = TRUE)
This installation of data.table has not been compiled with OpenMP support.
  omp_get_num_procs()            1
  R_DATATABLE_NUM_PROCS_PERCENT  unset (default 50)
  R_DATATABLE_NUM_THREADS        unset
  R_DATATABLE_THROTTLE           unset (default 1024)
  omp_get_thread_limit()         1
  omp_get_max_threads()          1
  OMP_THREAD_LIMIT               unset
  OMP_NUM_THREADS                1
  RestoreAfterFork               true
  data.table is using 1 threads with throttle==1024. See ?setDTthreads.
No list columns are present. Setting sep2='' otherwise quote='auto' would quote fields containing sep2.
Column writers: 12 5 5 
args.doRowNames=0 args.rowNames=0 doQuote=0 args.nrow=5 args.ncol=3 eolLen=1
maxLineLen=140. Found in 0.000s
Writing bom (false), yaml (0 characters) and column names (false) ... done in 0.002s
Writing 5 rows in 1 batches of 5 rows (each buffer size 8MB, showProgress=1, nth=1)
rm(temp)

Covariates

Here we create a covariates.txt file used by GWASToolKit for analysis.

library(tidyverse)
# for 'overall' analyses
c("Age Sex PC1 PC2 ORyear") %>% write_lines(paste0(SNP_loc, "/covariates.txt"))

# for sex-specific analyses
c("Age PC1 PC2 ORyear") %>% write_lines(paste0(SNP_loc, "/covariates.sex.txt"))

Phenotypes

Here we create a phenotypes.txt file used by GWASToolKit for analysis.

library(tidyverse)
c("Calcification", "Collagen", "Fat10", "Fat40", "IPH", "SMC_rankNorm", "MAC_rankNorm", "Neutrophils_rankNorm", "MastCells_rankNorm", "VesselDensity_rankNorm") %>% write_lines(paste0(SNP_loc, "/phenotypes.txt"))

c("Plaque_Vulnerability_Index") %>% write_lines(paste0(SNP_loc, "/phenotypes.pvi.txt"))

Session information


Version:      v1.2.1
Last update:  2023-06-14
Written by:   Sander W. van der Laan (s.w.vanderlaan-2[at]umcutrecht.nl).
Description:  Script to get some Athero-Express Biobank Study baseline characteristics.
Minimum requirements: R version 3.4.3 (2017-06-30) -- 'Single Candle', Mac OS X El Capitan

Changes log
* v1.2.1 Fixed issue with baseline writing.
* v1.2.0 Update to the study database. 
* v1.1.0 Major update to WORCS system. 
* v1.0.6 Small bug fixes.
* v1.0.5 Added png for overlap-figure.
* v1.0.5 Removed obsolete references to objects.
* v1.0.4 Fixed a mistake in the chr X sample-file creation. Now the order matches the chr X data.
* v1.0.3 Fixed weight of files (limit of 10Mb per file for templates). Renamed entire repo.
* v1.0.2 Added sex-specific .sample-files. Added GWASToolKit input-files.
* v1.0.0 Initial version. Add 'plaque vulnerability index', Fixed baseline table, added codes, and results. Created sample-files.

sessionInfo()
R version 4.3.0 (2023-04-21)
Platform: x86_64-apple-darwin22.4.0 (64-bit)
Running under: macOS 14.0

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib 
LAPACK: /usr/local/Cellar/r/4.3.0_1/lib/R/lib/libRlapack.dylib;  LAPACK version 3.11.0

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: Europe/Amsterdam
tzcode source: internal

attached base packages:
[1] grid      tools     stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] gridExtra_2.3        plyr_1.8.8           rmarkdown_2.22       patchwork_1.1.2.9000 labelled_2.11.0      sjPlot_2.8.14        UpSetR_1.4.0        
 [8] ggpubr_0.6.0         forestplot_3.1.1     abind_1.4-5          checkmate_2.2.0      pheatmap_1.0.12      devtools_2.4.5       usethis_2.2.0       
[15] BlandAltmanLeh_0.3.1 tableone_0.13.2      openxlsx_4.2.5.2     haven_2.5.2          eeptools_1.2.5       DT_0.28              knitr_1.43          
[22] lubridate_1.9.2      forcats_1.0.0        stringr_1.5.0        purrr_1.0.1          tibble_3.2.1         ggplot2_3.4.2        tidyverse_2.0.0     
[29] data.table_1.14.8    naniar_1.0.0         tidyr_1.3.0          dplyr_1.1.2          optparse_1.7.3       readr_2.1.4          pander_0.6.5        
[36] R.utils_2.12.2       R.oo_1.25.0          R.methodsS3_1.8.2    worcs_0.1.10         credentials_1.3.2   

loaded via a namespace (and not attached):
  [1] fs_1.6.2               matrixStats_1.0.0      spatstat.sparse_3.0-1  httr_1.4.6             RColorBrewer_1.1-3     insight_0.19.2        
  [7] gh_1.4.0               profvis_0.3.8          sctransform_0.3.5      backports_1.4.1        sjlabelled_1.2.0       utf8_1.2.3            
 [13] R6_2.5.1               lazyeval_0.2.2         uwot_0.1.14            prereg_0.6.0           urlchecker_1.0.1       withr_2.5.0           
 [19] sp_1.6-1               prettyunits_1.1.1      progressr_0.13.0       cli_3.6.1              performance_0.10.4     spatstat.explore_3.2-1
 [25] sandwich_3.0-2         labeling_0.4.2         sass_0.4.6             Seurat_4.3.0           mvtnorm_1.2-1          spatstat.data_3.0-1   
 [31] proxy_0.4-27           ggridges_0.5.4         pbapply_1.7-0          askpass_1.1            sessioninfo_1.2.2      parallelly_1.36.0     
 [37] rstudioapi_0.14        generics_0.1.3         vroom_1.6.3            crosstalk_1.2.0        ica_1.0-3              spatstat.random_3.1-5 
 [43] car_3.1-2              zip_2.3.0              Matrix_1.5-4.1         fansi_1.0.4            lifecycle_1.0.3        multcomp_1.4-23       
 [49] yaml_2.3.7             carData_3.0-5          Rtsne_0.16             promises_1.2.0.1       crayon_1.5.2           miniUI_0.1.1.1        
 [55] lattice_0.21-8         cowplot_1.1.1          sys_3.4.2              pillar_1.9.0           boot_1.3-28.1          estimability_1.4.1    
 [61] future.apply_1.11.0    codetools_0.2-19       leiden_0.4.3           glue_1.6.2             remotes_2.4.2          vcd_1.4-11            
 [67] vctrs_0.6.2            png_0.1-8              gtable_0.3.3           cachem_1.0.8           xfun_0.39              mime_0.12             
 [73] survey_4.2-1           coda_0.19-4            survival_3.5-5         tinytex_0.45           ellipsis_0.3.2         fitdistrplus_1.1-11   
 [79] TH.data_1.1-2          ROCR_1.0-11            nlme_3.1-162           bit64_4.0.5            RcppAnnoy_0.0.20       bslib_0.4.2           
 [85] irlba_2.3.5.1          KernSmooth_2.23-21     colorspace_2.1-0       DBI_1.1.3              tidyselect_1.2.0       processx_3.8.1        
 [91] emmeans_1.8.6          bit_4.0.5              compiler_4.3.0         curl_5.0.0             plotly_4.10.2          bayestestR_0.13.1     
 [97] scales_1.2.1           lmtest_0.9-40          callr_3.7.3            digest_0.6.31          goftest_1.2-3          spatstat.utils_3.0-3  
[103] minqa_1.2.5            htmltools_0.5.5        pkgconfig_2.0.3        rticles_0.25           lme4_1.1-33            fastmap_1.1.1         
[109] rlang_1.1.1            htmlwidgets_1.6.2      shiny_1.7.4            farver_2.1.1           jquerylib_0.1.4        zoo_1.8-12            
[115] jsonlite_1.8.5         magrittr_2.0.3         munsell_0.5.0          Rcpp_1.0.10            reticulate_1.29        visdat_0.6.0          
[121] stringi_1.7.12         MASS_7.3-60            pkgbuild_1.4.0         parallel_4.3.0         listenv_0.9.0          ggrepel_0.9.3         
[127] sjmisc_2.8.9           deldir_1.0-9           ggeffects_1.2.2        splines_4.3.0          tensor_1.5             hms_1.1.3             
[133] sjstats_0.18.2         ps_1.7.5               igraph_1.4.3           ranger_0.15.1          spatstat.geom_3.2-1    ggsignif_0.6.4        
[139] reshape2_1.4.4         pkgload_1.3.2          evaluate_0.21          SeuratObject_4.1.3     mitools_2.4            modelr_0.1.11         
[145] renv_0.17.3            nloptr_2.0.3           tzdb_0.4.0             httpuv_1.6.11          RANN_2.6.1             openssl_2.0.6         
[151] getopt_1.20.3          polyclip_1.10-4        future_1.32.0          scattermore_1.1        broom_1.0.4            xtable_1.8-4          
[157] e1071_1.7-13           rstatix_0.7.2          later_1.3.1            class_7.3-22           viridisLite_0.4.2      gert_1.9.2            
[163] arm_1.13-1             memoise_2.0.1          cluster_2.1.4          timechange_0.2.0       globals_0.16.2        

Saving environment

save.image(paste0(PROJECT_loc, "/",Today,".",PROJECTNAME,".SNP_analyses.RData"))
© 1979-2023 Sander W. van der Laan | s.w.vanderlaan[at]gmail.com | vanderlaan.science. |
LS0tCnRpdGxlOiAiR2VuZXRpYyBhbmFseXNlcyIKYXV0aG9yOiAiW1NhbmRlciBXLiB2YW4gZGVyIExhYW4sIFBoRF0oaHR0cHM6Ly92YW5kZXJsYWFuLnNjaWVuY2UpIHwgcy53LnZhbmRlcmxhYW5AZ21haWwuY29tIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgY2FjaGU6IHllcwogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBjb2xsYXBzZTogeWVzCiAgICBkZl9wcmludDogcGFnZWQKICAgIGZpZy5hbGlnbjogY2VudGVyCiAgICBmaWdfY2FwdGlvbjogeWVzCiAgICBmaWdfaGVpZ2h0OiA2CiAgICBmaWdfcmV0aW5hOiAyCiAgICBmaWdfd2lkdGg6IDcKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIHRoZW1lOiBsdW1lbgogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBubwogICAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMKbWFpbmZvbnQ6IEFyaWFsCnN1YnRpdGxlOiBBY2NvbXBhbnlpbmcgJ0FFX1RFTVBMQVRFJwplZGl0b3Jfb3B0aW9uczoKICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lCiAgbWFya2Rvd246IAogICAgd3JhcDogODAKYmlibGlvZ3JhcGh5OiByZWZlcmVuY2VzLmJpYgprbml0OiB3b3Jjczo6Y2l0ZV9hbGwKLS0tCgojIEdlbmVyYWwgU2V0dXAKCmBgYHtyIGVjaG8gPSBGQUxTRX0Kcm0obGlzdCA9IGxzKCkpCmBgYAoKYGBge3IgTG9jYWxTeXN0ZW0sIGVjaG8gPSBGQUxTRX0Kc291cmNlKCJzY3JpcHRzL2xvY2FsLnN5c3RlbS5SIikKYGBgCgpgYGB7ciBTb3VyY2UgZnVuY3Rpb25zfQpzb3VyY2UoInNjcmlwdHMvZnVuY3Rpb25zLlIiKQpgYGAKCmBgYHtyIGxvYWRpbmdfcGFja2FnZXMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnNvdXJjZSgic2NyaXB0cy9wYWNrMDEucGFja2FnZXMuUiIpCgpgYGAKCmBgYHtyIFNldHRpbmc6IENvbG9yc30KClRvZGF5ID0gZm9ybWF0KGFzLkRhdGUoYXMuUE9TSVhsdChTeXMudGltZSgpKSksICIlWSVtJWQiKQpUb2RheS5SZXBvcnQgPSBmb3JtYXQoYXMuRGF0ZShhcy5QT1NJWGx0KFN5cy50aW1lKCkpKSwgIiVBLCAlQiAlZCwgJVkiKQoKc291cmNlKCJzY3JpcHRzL2NvbG9ycy5SIikKCmBgYAoKYGBge3Igc2V0dXBfbm90ZWJvb2ssIGluY2x1ZGU9RkFMU0V9CiMgV2UgcmVjb21tZW5kIHRoYXQgeW91IHByZXBhcmUgeW91ciByYXcgZGF0YSBmb3IgYW5hbHlzaXMgaW4gJ3ByZXBhcmVfZGF0YS5SJywKIyBhbmQgZW5kIHRoYXQgZmlsZSB3aXRoIGVpdGhlciBvcGVuX2RhdGEoeW91cmRhdGEpLCBvciBjbG9zZWRfZGF0YSh5b3VyZGF0YSkuCiMgVGhlbiwgdW5jb21tZW50IHRoZSBsaW5lIGJlbG93IHRvIGxvYWQgdGhlIG9yaWdpbmFsIG9yIHN5bnRoZXRpYyBkYXRhCiMgKHdoaWNoZXZlciBpcyBhdmFpbGFibGUpLCB0byBhbGxvdyBhbnlvbmUgdG8gcmVwcm9kdWNlIHlvdXIgY29kZToKIyBsb2FkX2RhdGEoKQoKIyBmdXJ0aGVyIGRlZmluZSBzb21lIGtuaXRyLW9wdGlvbnMuCmtuaXRyOjpvcHRzX2NodW5rJHNldChmaWcud2lkdGggPSAxMiwgZmlnLmhlaWdodCA9IDgsIGZpZy5wYXRoID0gJ0ZpZ3VyZXMvJywgCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gVFJVRSwgIyBzaG93IHdhcm5pbmdzIGR1cmluZyBjb2RlYm9vayBnZW5lcmF0aW9uCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gVFJVRSwgIyBzaG93IG1lc3NhZ2VzIGR1cmluZyBjb2RlYm9vayBnZW5lcmF0aW9uCiAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IFRSVUUsICMgZG8gbm90IGludGVycnVwdCBjb2RlYm9vayBnZW5lcmF0aW9uIGluIGNhc2Ugb2YgZXJyb3JzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB1c3VhbGx5IGJldHRlciBmb3IgZGVidWdnaW5nCiAgICAgICAgICAgICAgICAgICAgICBlY2hvID0gVFJVRSwgICMgc2hvdyBSIGNvZGUKICAgICAgICAgICAgICAgICAgICAgIGV2YWwgPSBUUlVFKQoKZ2dwbG90Mjo6dGhlbWVfc2V0KGdncGxvdDI6OnRoZW1lX21pbmltYWwoKSkKIyBwYW5kZXI6OnBhbmRlck9wdGlvbnMoInRhYmxlLnNwbGl0LnRhYmxlIiwgSW5mKQpsaWJyYXJ5KCJ3b3JjcyIpCmxpYnJhcnkoInJtYXJrZG93biIpCgpgYGAKCgojIyBCYWNrZ3JvdW5kCgpDb2xsYWJvcmF0aW9uIHRvIHN0dWR5IGByIFRSQUlUX09GX0lOVEVSRVNUYCBpbiByZWxhdGlvbiB0byBhdGhlcm9zY2xlcm90aWMgcGxhcXVlcyBjaGFyYWN0ZXJpc3RpY3MuCgotICAgYEdlbmVzLnhsc3hgIC0gbGlzdCBvZiBnZW5lcyBvZiBpbnRlcmVzdC4gCi0gICBgVmFyaWFudHMueGxzeGAgLSBsaXN0IG9mIHZhcmlhbnQocykgb2YgaW50ZXJlc3QuIAoKYGBge3IgdGFyZ2V0cywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShvcGVueGxzeCkKCmdlbmVfbGlzdF9kZiA8LSByZWFkLnhsc3gocGFzdGUwKFRBUkdFVF9sb2MsICIvdGFyZ2V0cy54bHN4IiksIHNoZWV0ID0gIkdlbmVzIikKCmdlbmVfbGlzdCA8LSB1bmxpc3QoZ2VuZV9saXN0X2RmJEdlbmUpCmdlbmVfbGlzdAoKdmFyaWFudF9saXN0IDwtIHJlYWQueGxzeChwYXN0ZTAoVEFSR0VUX2xvYywgIi90YXJnZXRzLnhsc3giKSwgc2hlZXQgPSAiVmFyaWFudHMiKQoKRFQ6OmRhdGF0YWJsZSh2YXJpYW50X2xpc3QpCgpgYGAKCgojIyBUaGlzIG5vdGVib29rIAoKSW4gdGhpcyBub3RlYm9vayB3ZSBzZXR1cCB0aGUgZmlsZXMgZm9yIHRoZSBTTlAgYW5hbHlzaXMuIAoKIyMgQXRoZXJvLUV4cHJlc3MgQmlvYmFuayBTdHVkeQoKVGhlIFsqQXRoZXJvLUV4cHJlc3MgQmlvYmFuayBTdHVkeSAoQUUpKl0oaHR0cDovL3d3dy5hdGhlcm9leHByZXNzLm5sKXt0YXJnZXQ9Il9ibGFuayJ9IGNvbnRhaW5zIHBsYXF1ZSBtYXRlcmlhbCBvZgpwYXRpZW50cyB0aGF0IHVuZGVyd2VudCBlbmRhcnRlcmVjdG9teWF0IHR3byBEdXRjaCB0ZXJ0aWFyeSByZWZlcnJhbCBjZW50ZXJzLiBEZXRhaWxzIG9mIHRoZSBzdHVkeSBkZXNpZ24gd2VyZSBkZXNjcmliZWQKYmVmb3JlLiBCcmllZmx5LCBibG9vZCBhbmQgcGxhcXVlIG1hdGVyaWFsIHdlcmUgb2J0YWluZWQgZHVyaW5nIGVuZGFydGVyZWN0b215IGFuZCBzdG9yZWQgYXQgLTgwIOKEgy4gT25seSBjYXJvdGlkCmVuZGFydGVyZWN0b215IChDRUEpIHBhdGllbnRzIHdlcmUgaW5jbHVkZWQgaW4gdGhlIHByZXNlbnQgc3R1ZHkuIEFsbCBwYXRpZW50cyBwcm92aWRlZCBpbmZvcm1lZCBjb25zZW50IGFuZCB0aGUgc3R1ZHkKd2FzIGFwcHJvdmVkIGJ5IHRoZSBtZWRpY2FsIGV0aGljcyBjb21taXR0ZWUuCgojIyBBdGhlcm8tRXhwcmVzcyBHZW5vbWljcyBTdHVkeQoKIyMjIEROQSBpc29sYXRpb24gYW5kIGdlbm90eXBpbmcKCldlIGdlbm90eXBlZCB0aGUgQUUgaW4gdGhyZWUgc2VwYXJhdGUsIGJ1dCBjb25zZWN1dGl2ZSBleHBlcmltZW50cy4gSW4gc2hvcnQsIEROQSB3YXMgZXh0cmFjdGVkIGZyb20gRURUQSBibG9vZCBvciAod2hlbgpubyBibG9vZCB3YXMgYXZhaWxhYmxlKSBwbGFxdWUgc2FtcGxlcyBvZiAxLDg1OCBjb25zZWN1dGl2ZSBwYXRpZW50cyBmcm9tIHRoZSBBdGhlcm8tRXhwcmVzcyBCaW9iYW5rIFN0dWR5IGFuZCBnZW5vdHlwZWQKaW4gMyBiYXRjaGVzLgoKRm9yIHRoZSAqQXRoZXJvLUV4cHJlc3MgR2Vub21pY3MgU3R1ZHkgMSAoQUVHUzEpKiA4OTEgcGF0aWVudHMgKDYwMiBtYWxlcywgMjYyIGZlbWFsZXMsIDI3IHVua25vd24gc2V4KSwgaW5jbHVkZWQKYmV0d2VlbiAyMDAyIGFuZCAyMDA3LCB3ZXJlIGdlbm90eXBlZCAoNDQwLDc2MyBtYXJrZXJzKSB1c2luZyB0aGUgQWZmeW1ldHJpeCBHZW5vbWUtV2lkZSBIdW1hbiBTTlAgQXJyYXkgNS4wIChTTlA1KSBjaGlwCihBZmZ5bWV0cml4IEluYy4sIFNhbnRhIENsYXJhLCBDQSwgVVNBKSBhdCBbRXVyb2ZpbnMgR2Vub21pY3NdKGh0dHBzOi8vd3d3LmV1cm9maW5zZ2Vub21pY3MuZXUvKXt0YXJnZXQ9Il9ibGFuayJ9Cihmb3JtZXJseSBrbm93biBhcyBBUk9TKS4KCkZvciB0aGUgKkF0aGVyby1FeHByZXNzIEdlbm9taWNzIFN0dWR5IDIgKEFFR1MyKSogOTU0IHBhdGllbnRzICg2NDAgbWFrZXMsIDMxMyBmZW1hbGVzLCAxIHVua25vd24gc2V4KSwgaW5jbHVkZWQgYmV0d2VlbgoyMDAyIGFuZCAyMDEzLCB3ZXJlIGdlbm90eXBlZCAoNTg3LDM1MSBtYXJrZXJzKSB1c2luZyB0aGUgQWZmeW1ldHJpeCBBeGlvbeKThyBHVyBDRVUgMSBBcnJheSAoQXhNKSBhdCB0aGUgW0dlbm9tZSBBbmFseXNpcwpDZW50ZXJdKGh0dHBzOi8vd3d3LmhlbG1ob2x0ei1tdWVuY2hlbi5kZS9ub19jYWNoZS9nYWMvaW5kZXguaHRtbCl7dGFyZ2V0PSJfYmxhbmsifS4KCkZvciB0aGUgKkF0aGVyby1FeHByZXNzIEdlbm9taWNzIFN0dWR5IDMgKEFFR1MzKSogNjU4IHBhdGllbnRzICg0NDggbWFsZXMsIDIwMyBmZW1hbGVzLCA1IHVua25vd24gc2V4KSwgaW5jbHVkZWQgYmV0d2VlbgoyMDAyIGFuZCAyMDE2LCB3ZXJlIGdlbm90eXBlZCAoNjkzLDkzMSBtYXJrZXJzKSB1c2luZyB0aGUgSWxsdW1pbmEgR1NBIE1EIHYxIEJlYWRBcnJheSAoR1NBKSBhdCBbSHVtYW4gR2Vub21pY3MKRmFjaWxpdHksIEhVR0UtRl0oaHR0cDovL2dsaW1kbmEub3JnL2luZGV4Lmh0bWwpe3RhcmdldD0iX2JsYW5rIn0uCgpBbGwgZXhwZXJpbWVudHMgd2VyZSBjYXJyaWVkIG91dCBhY2NvcmRpbmcgdG8gT0VDRCBzdGFuZGFyZHMuCgojIyMgR2Vub3R5cGluZyBjYWxsaW5nCgpXZSB1c2VkIHRoZSBnZW5vdHlwaW5nIGNhbGxpbmcgYWxnb3JpdGhtcyBhcyBhZHZpc2VkIGJ5IEFmZnltZXRyaXggKEFFR1MxIGFuZCBBRUdTMikgYW5kIElsbHVtaW5hIChBRUdTMyk6CgotICAgQUVHUzE6IEJSTE1NLVAKLSAgIEFFR1MyOiBBeGlvbUdUMQotICAgQUVHUzM6IElsbHVtaW5hIEdlbm9tZVN0dWRpbwoKIyMjIFF1YWxpdHkgY29udHJvbCBhZnRlciBnZW5vdHlwaW5nCgpBZnRlciBnZW5vdHlwZSBjYWxsaW5nLCB3ZSBhZGhlcmVkIHRvIGNvbW11bml0eSBzdGFuZGFyZCBxdWFsaXR5IGNvbnRyb2wgYW5kIGFzc3VyYW5jZSAoUUNBKSBwcm9jZWR1cmVzIG9mIHRoZSBnZW5vdHlwZQpkYXRhIGZyb20gQUVHUzEsIEFFR1MyLCBhbmQgQUVHUzMuIFNhbXBsZXMgd2l0aCBsb3cgYXZlcmFnZSBnZW5vdHlwZSBjYWxsaW5nIGFuZCBzZXggZGlzY3JlcGFuY2llcyAoY29tcGFyZWQgdG8gdGhlCmNsaW5pY2FsIGRhdGEgYXZhaWxhYmxlKSB3ZXJlIGV4Y2x1ZGVkLiBUaGUgZGF0YSB3YXMgZnVydGhlciBmaWx0ZXJlZCBvbjoKCjEpICBpbmRpdmlkdWFsIChzYW1wbGUpIGNhbGwgcmF0ZSBcPiA5NyUsCjIpICBTTlAgY2FsbCByYXRlIFw+IDk3JSwKMykgIG1pbm9yIGFsbGVsZSBmcmVxdWVuY2llcyAoTUFGKSBcPiAzJSwKNCkgIGF2ZXJhZ2UgaGV0ZXJvenlnb3NpdHkgcmF0ZSDCsSAzLjAgcy5kLiwKNSkgIHJlbGF0ZWRuZXNzIChwaS1oYXQgXD4gMC4yMCksCjYpICBIYXJkeS0tV2VpbmJlcmcgRXF1aWxpYnJpdW0gKEhXRSBwIFw8IDEuMMOXMTA8c3VwPuKIkjNcPFxzdXBcPiksIGFuZAo3KSAgTW9ub21vcnBoaWMgU05QcyAoXDwgMS4ww5cxMDxzdXA+4oiSNlw8XHN1cFw+KS4KCkFmdGVyIFFDQSAyLDQ5MyBzYW1wbGVzIHJlbWFpbmVkLCAxMDggb2Ygbm9uLUV1cm9wZWFuIGRlc2NlbnQvYW5jZXN0cnksIGFuZCAxNTYgcmVsYXRlZCBwYWlycy4gVGhlc2UgY29tcHJpc2UgODkwCnNhbXBsZXMgYW5kIDQwNyw3MTIgU05QcyBpbiBBRUdTMSwgODY5IHNhbXBsZXMgYW5kIDUzNCw1MDggU05QcyBpbiBBRUdTMiwgYW5kIDY0OTk1NCBzYW1wbGVzIGFuZCA1MzQsNTA4IFNOUHMgaW4gQUVHUzMKcmVtYWluZWQuCgojIyMgSW1wdXRhdGlvbgoKQmVmb3JlIHBoYXNpbmcgdXNpbmcgU0hBUEVJVDIsIGRhdGEgd2FzIGxpZnRlZCB0byBnZW5vbWUgYnVpbGQgYjM3IHVzaW5nIHRoZSBsaWZ0T3ZlciB0b29sIGZyb20gVUNTQwooPGh0dHBzOi8vZ2Vub21lLnVjc2MuZWR1L2NnaS1iaW4vaGdMaWZ0T3Zlcj4pLiBGaW5hbGx5LCBkYXRhIHdhcyBpbXB1dGVkIHdpdGggMTAwMEcgcGhhc2UgMywgdmVyc2lvbiA1IGFuZCBIUkMgcmVsZWFzZQoxLjEgYXMgYSByZWZlcmVuY2UgdXNpbmcgdGhlIFtNaWNoaWdhbiBJbXB1dGF0aW9uIFNlcnZlcl0oaHR0cHM6Ly9pbXB1dGF0aW9uc2VydmVyLnNwaC51bWljaC5lZHUvKXt0YXJnZXQ9Il9ibGFuayJ9LgpUaGVzZSByZXN1bHRzIHdlcmUgZnVydGhlciBpbnRlZ3JhdGVkIHVzaW5nIFFDVE9PTCB2Miwgd2hlcmUgSFJDIGltcHV0ZWQgdmFyaWFudHMgYXJlIGdpdmVuIHByZWNlbmRlbmNlIG92ZXIgMTAwMEcgcGhhc2UKMyBpbXB1dGVkIHZhcmlhbnRzLgoKIyMjIFF1YWxpdHkgY29udHJvbCBhZnRlciBpbXB1dGF0aW9uCgpXZSBjb21wYXJlZCBxdWFsaXR5IG9mIHRoZSB0aHJlZSBBRUdTIGRhdGFzZXRzLCBhbmQgbGlzdGVkIHNvbWUgdmFyaWFibGVzIG9mIGludGVyZXN0LgoKLSAgIHNhbXBsZSB0eXBlIChFRFRBIGJsb29kIG9yIHBsYXF1ZSkKLSAgIGdlbm90eXBpbmcgY2hpcCB1c2VkCi0gICByZWFzb24gZm9yIGZpbHRlcmluZwoKV2UgY2hlY2tlZCB0aGUgc3R1ZHl0eXBlIChBRSBvciBub3QpLCBhbmQgKmlkZW50aXR5LWJ5LWRlc2NlbnQgKElCRCkqIHdpdGhpbiBhbmQgYmV0d2VlbiBkYXRhc2V0cyB0byBhaWQgaW4gc2FtcGxlCm1peHVwcywgZHVwbGljYXRlIHNhbXBsZSB1c2UsIGFuZCByZWxhdGVkbmVzcy4gSW4gYWRkaXRpb24sIGR1cmluZyBnZW5vdHlwaW5nIHF1YWxpdHkgY29udHJvbCBzYW1wbGVzIHdlcmUgaWRlbnRpZmllZAp0aGF0IGRldmlhdGVkIGZyb20gKkhhcmR5LVdlaW5iZXJnIEVxdWlsaWJyaXVtIChIV0UpKiwgaGFkIGRpc2NvcmRhbmNlIGluIHNleC1jb2RpbmcgYW5kIGdlbm90eXBlIHNleCwgYW5kIGRldmlhdGVkIGZyb20KdGhlICpwcmluY2lwYWwgY29tcG9uZW50IGFuYWx5c2lzIChQQ0EpKiBwbG90LgoKV2Ugd2lsbCBsb2FkIHRoZSBBdGhlcm8tRXhwcmVzcyBCaW9iYW5rIFN0dWR5IGRhdGEsIGFuZCBhbGwgdGhlIHNhbXBsZXMgdGhhdCB3ZXJlIHNlbmQgZm9yIGdlbm90eXBpbmcgYW5kIHRoZSBmaW5hbApRQydlZCBzYW1wbGVMaXN0LgoKIyBMb2FkaW5nIGRhdGEKCkxvYWRpbmcgQXRoZXJvLUV4cHJlc3MgQmlvYmFuayBTdHVkeSBjbGluaWNhbCBhbmQgYmlvYmFuayBkYXRhLCBhcyB3ZWxsIGFzIHRoZSBTYW1wbGVMaXN0IG9mIGdlbmV0aWMgZGF0YS4gV2Ugc2ltcGx5IGxvYWQgdGhlIHByZXZpb3VzbHkgc2F2ZWQgYFJEU2AtZmlsZSBhbmQgZXh0cmFjdCB0aGUgY2xpbmljYWwgZGF0YSBmcm9tIHRoYXQuCgpgYGB7ciBMb2FkQUVEQn0KY2F0KCIqIGdldCBBdGhlcm8tRXhwcmVzcyBCaW9iYW5rIFN0dWR5IERhdGFiYXNlLi4uXG4iKQoKQUVEQi5DRUEgPC0gcmVhZFJEUyhmaWxlID0gcGFzdGUwKE9VVF9sb2MsICIvMjAyMzA2MTQuIixUUkFJVF9PRl9JTlRFUkVTVCwiLkFFREIuQ0VBLlJEUyIpKQpBRURCLkNFQVsxOjEwLCAxOjEwXQpkaW0oQUVEQi5DRUEpCgpBRURCLmZ1bGwgPC0gcmVhZFJEUyhmaWxlID0gcGFzdGUwKE9VVF9sb2MsICIvMjAyMzA2MTQuIixUUkFJVF9PRl9JTlRFUkVTVCwiLkFFREIuRlVMTC5SRFMiKSkKQUVEQi5mdWxsWzE6MTAsIDE6MTBdCmRpbShBRURCLmZ1bGwpCgoKY2F0KCJcbiogZ2V0IEF0aGVyby1FeHByZXNzIEdlbm9taWNzIFN0dWR5IGtleXMuLi5cbiIpCkFFR1MxMjMuc2FtcGxlTGlzdC5rZXl0YWJsZSA8LSBmcmVhZChwYXN0ZTAoQUVHU1FDX2xvYywgIi9RQy9TRUxFQ1RJT05TLzIwMjAwNDE5LlFDLkFFR1MxMjMuc2FtcGxlTGlzdC5rZXl0YWJsZS50eHQiKSkKCmRpbShBRUdTMTIzLnNhbXBsZUxpc3Qua2V5dGFibGUpCiMgQUVHUzEyMy5zYW1wbGVMaXN0LmtleXRhYmxlWzE6MTAsIDE6MTBdCgoKYGBgCgoKIyBBdGhlcm8tRXhwcmVzcyBHZW5vbWljcyBTdHVkeQoKIyMgUHJlcGFyZSBiYXNlbGluZQoKTGV0J3MgY29tYmluZSB0aGUgZnVsbCBBdGhlcm8tRXhwcmVzcyBCaW9iYW5rIFN0dWR5IHdpdGggdGhlIGtleS10YWJsZSBjb250YWluaW5nIHRoZSBBRUdTIGRhdGEuCgo+IE5PVEU6IHRoaXMgc2hvdWxkIHN1bSB0byAyLDEyNCBzYW1wbGVzIHdpdGggZ2Vub3R5cGVzLgoKYGBge3IgY3JlYXRlIEFFR1N9CkFFR1MgPC0gbWVyZ2UoQUVEQi5mdWxsLCBBRUdTMTIzLnNhbXBsZUxpc3Qua2V5dGFibGUsIGJ5LnggPSAiU1RVRFlfTlVNQkVSIiwgYnkueSA9ICJTVFVEWV9OVU1CRVIiLCBzb3J0ID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgIGFsbCA9IFRSVUUpCgpkaW0oQUVHUykKCkFFR1MkVVBJRC55IDwtIE5VTEwKbmFtZXMoQUVHUylbbmFtZXMoQUVHUykgPT0gIlVQSUQueCJdIDwtICJVUElEIgpBRUdTJEFnZS55IDwtIE5VTEwKbmFtZXMoQUVHUylbbmFtZXMoQUVHUykgPT0gIkFnZS54Il0gPC0gIkFnZSIKCnRhYmxlKEFFR1MkQ0hJUCwgdXNlTkEgPSAiaWZhbnkiKQoKQUVHUyRHV0FTIDwtIEFFR1MkQ0hJUApBRUdTJEdXQVNbaXMubmEoQUVHUyRHV0FTKV0gPC0gIm5vdCBnZW5vdHlwZWQiCkFFR1MkR1dBU1tBRUdTJEdXQVMgIT0gIm5vdCBnZW5vdHlwZWQiXSA8LSAiZ2Vub3R5cGVkIgoKdGFibGUoQUVHUyRDSElQLCBBRUdTJEdXQVMsIHVzZU5BID0gImlmYW55IikKYGBgCgpBbHNvIGEgdmlzdWFsaXNhdGlvbiBvZiB0aGUgQUVHUyB3aXRoIEFFREIgb3ZlcmxhcHMuCgpgYGB7ciB2aXN1YWxpc2UgQUVHUyBvdmVybGFwcywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShVcFNldFIpCnJlcXVpcmUoZ2dwbG90MikKcmVxdWlyZShwbHlyKQpyZXF1aXJlKGdyaWRFeHRyYSkKcmVxdWlyZShncmlkKQoKQUVEQi5hdmFpbEdXQVMgPSBsaXN0KApBRUdTMSA9IHN1YnNldChBRUdTLCBDSElQID09ICJBZmZ5U05QNSIsIHNlbGVjdCA9IGMoIlNUVURZX05VTUJFUiIpKVssMV0sCkFFR1MyID0gc3Vic2V0KEFFR1MsIENISVAgPT0gIkFmZnlBeGlvbUNFVSIsIHNlbGVjdCA9IGMoIlNUVURZX05VTUJFUiIpKVssMV0sCkFFR1MzID0gc3Vic2V0KEFFR1MsIENISVAgPT0gIklsbEdTQSIsIHNlbGVjdCA9IGMoIlNUVURZX05VTUJFUiIpKVssMV0sCkFFREIgPSBBRUdTJFNUVURZX05VTUJFUikKCnAxIDwtIFVwU2V0Ujo6dXBzZXQoZnJvbUxpc3QoQUVEQi5hdmFpbEdXQVMpLCAKICAgICAgICAgICAgICAgICAgICBzZXRzID0gYygiQUVEQiIsICJBRUdTMSIsICJBRUdTMiIsICJBRUdTMyIpLCAKICAgICAgICAgICAgICAgICAgICBtYWluLmJhci5jb2xvciA9IGModWl0aG9mX2NvbG9yWzE1XSwgdWl0aG9mX2NvbG9yWzNdLCB1aXRob2ZfY29sb3JbMl0sIHVpdGhvZl9jb2xvclsyMV0pLCAKICAgICAgICAgICAgICAgICAgICBtYWluYmFyLnkubGFiZWwJPSAiaW50ZXJzZWN0aW9uIHNhbXBsZSBzaXplIiwgCiAgICAgICAgICAgICAgICAgICAgc2V0cy5iYXIuY29sb3IgPSBjKHVpdGhvZl9jb2xvclsxNV0sIHVpdGhvZl9jb2xvclsyXSwgdWl0aG9mX2NvbG9yWzNdLCB1aXRob2ZfY29sb3JbMjFdKSwgCiAgICAgICAgICAgICAgICAgICAgc2V0cy54LmxhYmVsID0gInNhbXBsZSBzaXplIiwga2VlcC5vcmRlciA9IFRSVUUpCgpwMQoKcGRmKHBhc3RlMChQTE9UX2xvYywgIi8iLCBUb2RheSwgIi5vdmVybGFwLkFFREJfQUVHUzEyMy5VcFNldFIucGRmIikpCiAgcDEKZGV2Lm9mZigpCgpwbmcocGFzdGUwKFBMT1RfbG9jLCAiLyIsIFRvZGF5LCAiLm92ZXJsYXAuQUVEQl9BRUdTMTIzLlVwU2V0Ui5wbmciKSkKICBwMQpkZXYub2ZmKCkKCnJtKHAxKQoKYGBgCj4gUGxlYXNlIHJlZmVyIHRvIHRoZSBgQUVEQi5DRUEuYmFzZWxpbmUuaHRtbGAgZG9jdW1lbnQgZm9yIHRoZSBkZXRhaWxzIG9uIHRoZSBpbmZvcm1lZCBjb25zZW50IHNlbGVjdGlvbi4KCmBgYHtyIFNwZWNpZmljU2VsZWN0aW9ufQp0YWJsZShBRUdTJEFydGVyeV9zdW1tYXJ5LCBBRUdTJFFDMjAxOF9GSUxURVIpCnRhYmxlKEFFR1MkaW5mb3JtZWRjb25zZW50LCBBRUdTJFFDMjAxOF9GSUxURVIpCkFFR1NzZWxlY3QgPC0gc3Vic2V0KEFFR1MsIAogICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm1pc3NpbmciICYgIyB3ZSBhcmUgcmVhbGx5IHN0cmljdCBpbiBzZWxlY3RpbmcgYmFzZWQgb24gJ2luZm9ybWVkIGNvbnNlbnQnIQogICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vLCBkaWVkIiAmIAogICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBjb21tZXJpY2FsIGJ1c2luZXNzIiAmIAogICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gbWVkaWNhbCBpbmZvLCBubyBjb21tZXJjaWFsIGJ1c2luZXNzIiAmIAogICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gY29tbWVyaWNhbCBidXNpbmVzcyIgJiAKICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIGhlYWx0aCB0cmVhdG1lbnQsIG5vIG1lZGljYWwgaW5mbywgbm8gY29tbWVyY2lhbCBidXNpbmVzcyIgJiAKICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gaGVhbHRoIHRyZWF0bWVudCIgJiAKICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMiICYgCiAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIGhlYWx0aCB0cmVhdG1lbnQgd2hlbiBwb3NzaWJsZSIgJiAKICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSIgJiAKICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIGhlYWx0aCB0cmVhdG1lbnQsIG5vIG1lZGljYWwgaW5mbyIgJiAKICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIGhlYWx0aCB0cmVhdG1lbnQsIG5vIGNvbW1lcmNpYWwgYnVzaW5lc3MiICYgCiAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIGRvZXNuJ3Qgd2FudCB0byIgJiAKICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJubywgdW5hYmxlIHRvIHNpZ24iICYgCiAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIG5vIHJlYWN0aW9uIiAmIAogICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vLCBsb3N0IiAmIAogICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vLCB0b28gb2xkIiAmIAogICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vIChuZXZlciBhc2tlZCBmb3IgSUMgYmVjYXVzZSB0aGVyZSB3YXMgbm8gdGlzc3VlKSIgJiAKICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJubywgZW5kcG9pbnQiICYgCiAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAid2lsIG5pZXRzIGludnVsbGVuLCB3ZWwgYWxsZXMgZ2VicnVpa2VuIiAmIAogICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vb2l0IGdlaW5jbHVkZWVyZCIgJiAKICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIEROQSIpCgpBRUdTc2VsZWN0LkNFQSA8LSBzdWJzZXQoQUVHUywgIWlzLm5hKFFDMjAxOF9GSUxURVIpICYgUUMyMDE4X0ZJTFRFUiAhPSAiaXNzdWUiICYgUUMyMDE4X0ZJTFRFUiAhPSAiZmFtaWx5X2Rpc2NhcmQiICYKICAgICAgICAgICAgICAgICAgICAgKEFydGVyeV9zdW1tYXJ5ID09ICJjYXJvdGlkIChsZWZ0ICYgcmlnaHQpIiB8IEFydGVyeV9zdW1tYXJ5ID09ICJvdGhlciBjYXJvdGlkIGFydGVyaWVzIChjb21tb24sIGV4dGVybmFsKSIpICYgIyB3ZSBvbmx5IHdhbnQgY2Fyb3RpZHMKICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJtaXNzaW5nIiAmICMgd2UgYXJlIHJlYWxseSBzdHJpY3QgaW4gc2VsZWN0aW5nIGJhc2VkIG9uICdpbmZvcm1lZCBjb25zZW50JyEKICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJubywgZGllZCIgJiAKICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gY29tbWVyaWNhbCBidXNpbmVzcyIgJiAKICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIG1lZGljYWwgaW5mbywgbm8gY29tbWVyY2lhbCBidXNpbmVzcyIgJiAKICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIGhlYWx0aCB0cmVhdG1lbnQsIG5vIGNvbW1lcmljYWwgYnVzaW5lc3MiICYgCiAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIHF1ZXN0aW9ubmFpcmVzLCBubyBoZWFsdGggdHJlYXRtZW50LCBubyBtZWRpY2FsIGluZm8sIG5vIGNvbW1lcmNpYWwgYnVzaW5lc3MiICYgCiAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIGhlYWx0aCB0cmVhdG1lbnQiICYgCiAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIHF1ZXN0aW9ubmFpcmVzIiAmIAogICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBoZWFsdGggdHJlYXRtZW50IHdoZW4gcG9zc2libGUiICYgCiAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUiICYgCiAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIHF1ZXN0aW9ubmFpcmVzLCBubyBoZWFsdGggdHJlYXRtZW50LCBubyBtZWRpY2FsIGluZm8iICYgCiAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIHF1ZXN0aW9ubmFpcmVzLCBubyBoZWFsdGggdHJlYXRtZW50LCBubyBjb21tZXJjaWFsIGJ1c2luZXNzIiAmIAogICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vLCBkb2Vzbid0IHdhbnQgdG8iICYgCiAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIHVuYWJsZSB0byBzaWduIiAmIAogICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vLCBubyByZWFjdGlvbiIgJiAKICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJubywgbG9zdCIgJiAKICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJubywgdG9vIG9sZCIgJiAKICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJubyAobmV2ZXIgYXNrZWQgZm9yIElDIGJlY2F1c2UgdGhlcmUgd2FzIG5vIHRpc3N1ZSkiICYgCiAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIGVuZHBvaW50IiAmIAogICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIndpbCBuaWV0cyBpbnZ1bGxlbiwgd2VsIGFsbGVzIGdlYnJ1aWtlbiIgJiAKICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJub29pdCBnZWluY2x1ZGVlcmQiICYgCiAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyBETkEiKQoKZGltKEFFR1NzZWxlY3QpCgp0YWJsZShBRUdTc2VsZWN0JEFydGVyeV9zdW1tYXJ5LCBBRUdTc2VsZWN0JFFDMjAxOF9GSUxURVIpCnRhYmxlKEFFR1NzZWxlY3QkQXJ0ZXJ5X3N1bW1hcnksIEFFR1NzZWxlY3QkQ0hJUCkKdGFibGUoQUVHU3NlbGVjdCRRQzIwMThfRklMVEVSLCBBRUdTc2VsZWN0JENISVApCnRhYmxlKEFFR1NzZWxlY3QkUUMyMDE4X0ZJTFRFUiwgQUVHU3NlbGVjdCRTQU1QTEVfVFlQRSkKCkFFREIudGVtcCA8LSBzdWJzZXQoQUVHU3NlbGVjdCwgIHNlbGVjdCA9IGMoIlNUVURZX05VTUJFUiIsICJVUElEIiwgIkFnZSIsICJHZW5kZXIiLCAiSG9zcGl0YWwiLCAiQXJ0ZXJ5X3N1bW1hcnkiLCAiUUMyMDE4X0ZJTFRFUiIsICJDSElQIiwgIlNBTVBMRV9UWVBFIikpCnJlcXVpcmUobGFiZWxsZWQpCkFFREIudGVtcCRHZW5kZXIgPC0gdG9fZmFjdG9yKEFFREIudGVtcCRHZW5kZXIpCkFFREIudGVtcCRIb3NwaXRhbCA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJEhvc3BpdGFsKQpBRURCLnRlbXAkQXJ0ZXJ5X3N1bW1hcnkgPC0gdG9fZmFjdG9yKEFFREIudGVtcCRBcnRlcnlfc3VtbWFyeSkKQUVEQi50ZW1wJFFDMjAxOF9GSUxURVIgPC0gdG9fZmFjdG9yKEFFREIudGVtcCRRQzIwMThfRklMVEVSKQpBRURCLnRlbXAkQ0hJUCA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJENISVApCkFFREIudGVtcCRTQU1QTEVfVFlQRSA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJFNBTVBMRV9UWVBFKQoKRFQ6OmRhdGF0YWJsZShBRURCLnRlbXBbMToxMCxdLCBjYXB0aW9uID0gIkV4Y2VycHQgb2YgdGhlIHdob2xlIEFFREIuIiwgcm93bmFtZXMgPSBGQUxTRSkKCnJtKEFFREIudGVtcCkKCgpgYGAKCiMjIEF0aGVyby1FeHByZXNzIEdlbm9taWNzIFN0dWR5IEJhc2VsaW5lIENoYXJhY3RlcmlzdGljcwoKU2hvd2luZyB0aGUgYmFzZWxpbmUgdGFibGUgb2YgdGhlIEF0aGVyby1FeHByZXNzIEdlbm9taWNzIFN0dWR5LgoKYGBge3IgQmFzZWxpbmUgU2FtcGxlU2VsZWN0OiBwcmVwYXJlfQojIENyZWF0ZSBiYXNlbGluZSB0YWJsZXMKIyBodHRwOi8vcnN0dWRpby1wdWJzLXN0YXRpYy5zMy5hbWF6b25hd3MuY29tLzEzMzIxX2RhMzE0NjMzZGI5MjRkYzc4OTg2YTg1MDgxM2E1MGQ1Lmh0bWwKQUVHU3NlbGVjdCRHV0FTIDwtIHRvX2ZhY3RvcihBRUdTc2VsZWN0JEdXQVMpCkFFR1NzZWxlY3QkQ0hJUCA8LSB0b19mYWN0b3IoQUVHU3NlbGVjdCRDSElQKQpBRUdTc2VsZWN0JFBDQSA8LSB0b19mYWN0b3IoQUVHU3NlbGVjdCRQQ0EpCkFFR1NzZWxlY3QkU0FNUExFX1RZUEUgPC0gdG9fZmFjdG9yKEFFR1NzZWxlY3QkU0FNUExFX1RZUEUpCkFFR1NzZWxlY3QkaW5mb3JtZWRjb25zZW50IDwtIHRvX2ZhY3RvcihBRUdTc2VsZWN0JGluZm9ybWVkY29uc2VudCkKQUVHU3NlbGVjdCRBcnRlcnlfc3VtbWFyeSA8LSB0b19mYWN0b3IoQUVHU3NlbGVjdCRBcnRlcnlfc3VtbWFyeSkKCkFFR1NzZWxlY3QuQ0VBJEdXQVMgPC0gdG9fZmFjdG9yKEFFR1NzZWxlY3QuQ0VBJEdXQVMpCkFFR1NzZWxlY3QuQ0VBJENISVAgPC0gdG9fZmFjdG9yKEFFR1NzZWxlY3QuQ0VBJENISVApCkFFR1NzZWxlY3QuQ0VBJFBDQSA8LSB0b19mYWN0b3IoQUVHU3NlbGVjdC5DRUEkUENBKQpBRUdTc2VsZWN0LkNFQSRTQU1QTEVfVFlQRSA8LSB0b19mYWN0b3IoQUVHU3NlbGVjdC5DRUEkU0FNUExFX1RZUEUpCkFFR1NzZWxlY3QuQ0VBJGluZm9ybWVkY29uc2VudCA8LSB0b19mYWN0b3IoQUVHU3NlbGVjdC5DRUEkaW5mb3JtZWRjb25zZW50KQpBRUdTc2VsZWN0LkNFQSRBcnRlcnlfc3VtbWFyeSA8LSB0b19mYWN0b3IoQUVHU3NlbGVjdC5DRUEkQXJ0ZXJ5X3N1bW1hcnkpCgpjYXQoIj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIpCmNhdCgiQ1JFQVRFIEJBU0VMSU5FIFRBQkxFXG4iKQoKIyBCYXNlbGluZSB0YWJsZSB2YXJpYWJsZXMKYmFzZXRhYmxlX3ZhcnMgPSBjKCJIb3NwaXRhbCIsIAogICAgICAgICAgICAgICAgICAgIkFnZSIsICJHZW5kZXIiLCAKICAgICAgICAgICAgICAgICAgICJUQ19maW5hbCIsICJMRExfZmluYWwiLCAiSERMX2ZpbmFsIiwgIlRHX2ZpbmFsIiwgCiAgICAgICAgICAgICAgICAgICAic3lzdG9saWMiLCAiZGlhc3RvbGkiLCAiR0ZSX01EUkQiLCAiQk1JIiwgCiAgICAgICAgICAgICAgICAgICAiS0RPUUkiLCAiQk1JX1dITyIsIAogICAgICAgICAgICAgICAgICAgIlNtb2tlckN1cnJlbnQiLCAiZUNpZ2FyZXR0ZXMiLCAiZVBhY2tZZWFyc1Ntb2tpbmciLAogICAgICAgICAgICAgICAgICAgIkRpYWJldGVzU3RhdHVzIiwgIkh5cGVydGVuc2lvbi5zZWxmcmVwb3J0IiwgIkh5cGVydGVuc2lvbi5zZWxmcmVwb3J0ZHJ1ZyIsICJIeXBlcnRlbnNpb24uY29tcG9zaXRlIiwgCiAgICAgICAgICAgICAgICAgICAiSHlwZXJ0ZW5zaW9uLmRydWdzIiwgIk1lZC5hbnRpY29hZ3VsYW50cyIsICJNZWQuYWxsLmFudGlwbGF0ZWxldCIsICJNZWQuU3RhdGluLkxMRCIsIAogICAgICAgICAgICAgICAgICAgIlN0cm9rZV9EeCIsICJzeW1wdCIsICJTeW1wdG9tcy41RyIsICJyZXN0ZW5vcyIsCiAgICAgICAgICAgICAgICAgICAiRVBfY29tcG9zaXRlIiwgIkVQX2NvbXBvc2l0ZV90aW1lIiwKICAgICAgICAgICAgICAgICAgICJtYWNtZWFuMCIsICJzbWNtZWFuMCIsICJNYWNyb3BoYWdlcy5iaW4iLCAiU01DLmJpbiIsICJuZXV0cm9waGlscyIsICJNYXN0X2NlbGxzX3BsYXF1ZSIsICJ2ZXNzZWxfZGVuc2l0eV9hdmVyYWdlZCIsCiAgICAgICAgICAgICAgICAgICAiSVBILmJpbiIsIAogICAgICAgICAgICAgICAgICAgIkNhbGMuYmluIiwgIkNvbGxhZ2VuLmJpbiIsIAogICAgICAgICAgICAgICAgICAgIkZhdC5iaW5fMTAiLCAiRmF0LmJpbl80MCIsICJPdmVyYWxsUGxhcXVlUGhlbm90eXBlIiwgIlBsYXF1ZV9WdWxuZXJhYmlsaXR5X0luZGV4IiwKICAgICAgICAgICAgICAgICAgICJTTUNfcmFua05vcm0iLCAiTUFDX3JhbmtOb3JtIiwgIk5ldXRyb3BoaWxzX3JhbmtOb3JtIiwgIk1hc3RDZWxsc19yYW5rTm9ybSIsICJWZXNzZWxEZW5zaXR5X3JhbmtOb3JtIiwKICAgICAgICAgICAgICAgICAgICJHV0FTIiwgIkNISVAiLCAiUENBIiwgIkFydGVyeV9zdW1tYXJ5IiwKICAgICAgICAgICAgICAgICAgICJQQ1NLOV9wbGFzbWEiLCAiUENTSzlfcGxhc21hX3JhbmtOb3JtIikKCmJhc2V0YWJsZV9iaW4gPSBjKCJHZW5kZXIiLCAKICAgICAgICAgICAgICAgICAgIktET1FJIiwgIkJNSV9XSE8iLCAKICAgICAgICAgICAgICAgICAgIlNtb2tlckN1cnJlbnQiLCAKICAgICAgICAgICAgICAgICAgIkRpYWJldGVzU3RhdHVzIiwgIkh5cGVydGVuc2lvbi5zZWxmcmVwb3J0IiwgIkh5cGVydGVuc2lvbi5zZWxmcmVwb3J0ZHJ1ZyIsICJIeXBlcnRlbnNpb24uY29tcG9zaXRlIiwgCiAgICAgICAgICAgICAgICAgICJIeXBlcnRlbnNpb24uZHJ1Z3MiLCAiTWVkLmFudGljb2FndWxhbnRzIiwgIk1lZC5hbGwuYW50aXBsYXRlbGV0IiwgIk1lZC5TdGF0aW4uTExEIiwgCiAgICAgICAgICAgICAgICAgICJTdHJva2VfRHgiLCAic3ltcHQiLCAiU3ltcHRvbXMuNUciLCAicmVzdGVub3MiLAogICAgICAgICAgICAgICAgICAiRVBfY29tcG9zaXRlIiwgIk1hY3JvcGhhZ2VzLmJpbiIsICJTTUMuYmluIiwKICAgICAgICAgICAgICAgICAgIklQSC5iaW4iLCAKICAgICAgICAgICAgICAgICAgIkNhbGMuYmluIiwgIkNvbGxhZ2VuLmJpbiIsIAogICAgICAgICAgICAgICAgICAiRmF0LmJpbl8xMCIsICJGYXQuYmluXzQwIiwgIk92ZXJhbGxQbGFxdWVQaGVub3R5cGUiLCAiUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXgiLAogICAgICAgICAgICAgICAgICAiR1dBUyIsICJDSElQIiwgIlBDQSIsICJBcnRlcnlfc3VtbWFyeSIpCgpiYXNldGFibGVfYmluCgpiYXNldGFibGVfY29uID0gYmFzZXRhYmxlX3ZhcnNbIWJhc2V0YWJsZV92YXJzICVpbiUgYmFzZXRhYmxlX2Jpbl0KYmFzZXRhYmxlX2NvbgoKYGBgCgpBbGwgQXRoZXJvLUV4cHJlc3MgR2Vub21pY3MgU3R1ZHkgZGF0YSAobiA9IDIsMDExKSwgY29tcGFyZWQgdG8gdGhlICpyZW1haW5pbmcqLCBcX3VuX2dlbm90eXBlZCBBdGhlcm8tRXhwcmVzcyBCaW9iYW5rClN0dWR5LgoKYGBge3IgQmFzZWxpbmUgU2FtcGxlU2VsZWN0OiBWaXN1YWxpemUsIHdob2xlfQpjYXQoIlxuPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIikKY2F0KCJESVNQTEFZIEJBU0VMSU5FIFRBQkxFXG4iKQoKQUVHU3NlbGVjdC50YWJsZU9uZSA9IHByaW50KENyZWF0ZVRhYmxlT25lKHZhcnMgPSBiYXNldGFibGVfdmFycywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBmYWN0b3JWYXJzID0gYmFzZXRhYmxlX2JpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJhdGEgPSAiR1dBUyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IEFFR1NzZWxlY3QsIGluY2x1ZGVOQSA9IFRSVUUpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBub25ub3JtYWwgPSBjKCksIG1pc3NpbmcgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgIHF1b3RlID0gRkFMU0UsIG5vU3BhY2VzID0gRkFMU0UsIHNob3dBbGxMZXZlbHMgPSBUUlVFLCBleHBsYWluID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0ID0gInBmIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29udERpZ2l0cyA9IDMpWywxOjZdCmBgYAoKCkJhc2VsaW5lIG9mIHRoZSB2YWxpZCwgQ0VBIGFuZCBnZW5vdHlwZWQgZGF0YS4KCmBgYHtyIEJhc2VsaW5lIFNhbXBsZVNlbGVjdDogVmlzdWFsaXplLCBDRUF9CkFFR1NzZWxlY3QuQ0VBLnRhYmxlT25lID0gcHJpbnQoQ3JlYXRlVGFibGVPbmUodmFycyA9IGJhc2V0YWJsZV92YXJzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGZhY3RvclZhcnMgPSBiYXNldGFibGVfYmluLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmF0YSA9ICJHZW5kZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBBRUdTc2VsZWN0LkNFQSwgaW5jbHVkZU5BID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgICAgICAgIG5vbm5vcm1hbCA9IGMoKSwgbWlzc2luZyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgcXVvdGUgPSBGQUxTRSwgbm9TcGFjZXMgPSBGQUxTRSwgc2hvd0FsbExldmVscyA9IFRSVUUsIGV4cGxhaW4gPSBUUlVFLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXQgPSAicGYiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBjb250RGlnaXRzID0gMylbLDE6Nl0KYGBgCgojIyMgQmFzZWxpbmUgd3JpdGluZwoKTGV0J3Mgc2F2ZSB0aGUgYmFzZWxpbmUgY2hhcmFjdGVyaXN0aWNzIG9mIHRoZSBBdGhlcm8tRXhwcmVzcyBHZW5vbWljcyBTdHVkeS4KCmBgYHtyIEJhc2VsaW5lIFNhbXBsZVNlbGVjdGlvbjogd3JpdGUgQUVHU30KIyBXcml0ZSBiYXNldGFibGUKcmVxdWlyZShvcGVueGxzeCkKCndyaXRlLnhsc3goZmlsZSA9IHBhc3RlMChCQVNFTElORV9sb2MsICIvIixUb2RheSwiLiIsUFJPSkVDVE5BTUUsIi5BRUdTLkJhc2VsaW5lVGFibGUueGxzeCIpLCAKICAgICAgICAgICBmb3JtYXQoYXMuZGF0YS5mcmFtZShBRUdTc2VsZWN0LnRhYmxlT25lKSwgZGlnaXRzID0gNSwgc2NpZW50aWZpYyA9IEZBTFNFKSwKICAgICAgICAgICByb3dOYW1lcyA9IFRSVUUsIAogICAgICAgICAgIGNvbE5hbWVzID0gVFJVRSwgCiAgICAgICAgICAgc2hlZXROYW1lID0gIkFFR1NfQmFzZV9BRURCIiwgb3ZlcndyaXRlID0gVFJVRSkKCndyaXRlLnhsc3goZmlsZSA9IHBhc3RlMChCQVNFTElORV9sb2MsICIvIixUb2RheSwiLiIsUFJPSkVDVE5BTUUsIi5BRUdTLkNFQS5CYXNlbGluZVRhYmxlLnhsc3giKSwgCiAgICAgICAgICAgZm9ybWF0KGFzLmRhdGEuZnJhbWUoQUVHU3NlbGVjdC5DRUEudGFibGVPbmUpLCBkaWdpdHMgPSA1LCBzY2llbnRpZmljID0gRkFMU0UpLAogICAgICAgICAgIHJvd05hbWVzID0gVFJVRSwgCiAgICAgICAgICAgY29sTmFtZXMgPSBUUlVFLCAKICAgICAgICAgICBzaGVldE5hbWUgPSAiQUVHU19CYXNlX0NFQV9zZXgiLCBvdmVyd3JpdGUgPSBUUlVFKQoKYGBgCgojIFNhbXBsZUxpc3RzCgojIyBBdXRvc29tYWwgZGF0YS4KCldlIGFyZSByZWFkeSB0byBtYWtlIGEgc2FtcGxlTGlzdCBmb3IgdXNlIHdpdGggdGhlIGltcHV0ZWQgZGF0YS4KCmBgYHtyIFByZXAgU2FtcGxlU2VsZWN0fQpyZXF1aXJlKG9wZW54bHN4KQoKdGVtcCA8LSBzdWJzZXQoQUVHUywKICAgICAgICAgICAgICAgR1dBUyA9PSAiZ2Vub3R5cGVkIiwKICAgICAgICAgICAgICAgc2VsZWN0ID0gYygiSURfMSIsICJJRF8yIiwgIlVQSUQiLCAiU1RVRFlfTlVNQkVSIiwgIyBJRF8yIGlzIHRoZSBvcmRlciBvZiBzYW1wbGVzIQogICAgICAgICAgICAgICAgICAgICAgICAgICJRQzIwMThfRklOQUwiLCAiUUMyMDE4X0ZJTFRFUiIsICJPcmlnaW5hbE9yZGVyX3Bvc3RNaWNoSW1wX1FDIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiQUVHU190eXBlIiwgIkNISVAiLCAiU1RVRFlfVFlQRSIsICJTQU1QTEVfVFlQRSIsICJQQ0EiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJQQzEiLCAiUEMyIiwgIlBDMyIsICJQQzQiLCAiUEM1IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiUEM2IiwgIlBDNyIsICJQQzgiLCAiUEM5IiwgIlBDMTAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJTZXgiLCAiQWdlIiwgIk9SeWVhciIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICJDYWxjLmJpbiIsICJDb2xsYWdlbi5iaW4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAiRmF0LmJpbl8xMCIsICJGYXQuYmluXzQwIiwgIklQSC5iaW4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAiU01DX3JhbmtOb3JtIiwgIk1BQ19yYW5rTm9ybSIsICJOZXV0cm9waGlsc19yYW5rTm9ybSIsICJNYXN0Q2VsbHNfcmFua05vcm0iLCAiVmVzc2VsRGVuc2l0eV9yYW5rTm9ybSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlBsYXF1ZV9WdWxuZXJhYmlsaXR5X0luZGV4IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiUENTSzlfcGxhc21hIiwgIlBDU0s5X3BsYXNtYV9yYW5rTm9ybSIpKSAjIFNlbGVjdCBzb21lIHBoZW5vdHlwZSBvZiBpbnRlcmVzdApkaW0odGVtcCkKCiMgRml4IHRoaW5ncwphdHRhY2godGVtcCkKCnRlbXBbLCJDYWxjaWZpY2F0aW9uIl0gPC0gTkEKdGVtcCRDYWxjaWZpY2F0aW9uW0NhbGMuYmluID09ICJuby9taW5vciJdIDwtICJjb250cm9sIgp0ZW1wJENhbGNpZmljYXRpb25bQ2FsYy5iaW4gPT0gIm1vZGVyYXRlL2hlYXZ5Il0gPC0gImNhc2UiCgp0ZW1wWywiQ29sbGFnZW4iXSA8LSBOQQp0ZW1wJENvbGxhZ2VuW0NvbGxhZ2VuLmJpbiA9PSAibm8vbWlub3IiXSA8LSAiY29udHJvbCIKdGVtcCRDb2xsYWdlbltDb2xsYWdlbi5iaW4gPT0gIm1vZGVyYXRlL2hlYXZ5Il0gPC0gImNhc2UiCgp0ZW1wWywiRmF0MTAiXSA8LSBOQQp0ZW1wJEZhdDEwW0ZhdC5iaW5fMTAgPT0gIjwxMCUiXSA8LSAiY29udHJvbCIKdGVtcCRGYXQxMFtGYXQuYmluXzEwID09ICI+MTAlIl0gPC0gImNhc2UiCgp0ZW1wWywiRmF0NDAiXSA8LSBOQQp0ZW1wJEZhdDQwW0ZhdC5iaW5fNDAgPT0gIjw0MCUiXSA8LSAiY29udHJvbCIKdGVtcCRGYXQ0MFtGYXQuYmluXzQwID09ICI+NDAlIl0gPC0gImNhc2UiCgp0ZW1wWywiSVBIIl0gPC0gTkEKdGVtcCRJUEhbSVBILmJpbiA9PSAibm8iXSA8LSAiY29udHJvbCIKdGVtcCRJUEhbSVBILmJpbiA9PSAieWVzIl0gPC0gImNhc2UiCgp0ZW1wWywiUFZJIl0gPC0gTkEKdGVtcCRQVklbUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXggPT0gIjAiXSA8LSAiUFZJX2NhdDAiCnRlbXAkUFZJW1BsYXF1ZV9WdWxuZXJhYmlsaXR5X0luZGV4ID09ICIxIl0gPC0gIlBWSV9jYXQxIgp0ZW1wJFBWSVtQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCA9PSAiMiJdIDwtICJQVklfY2F0MiIKdGVtcCRQVklbUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXggPT0gIjMiXSA8LSAiUFZJX2NhdDMiCnRlbXAkUFZJW1BsYXF1ZV9WdWxuZXJhYmlsaXR5X0luZGV4ID09ICI0Il0gPC0gIlBWSV9jYXQ0Igp0ZW1wJFBWSVtQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCA9PSAiNSJdIDwtICJQVklfY2F0NSIKCnRlbXAkUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXggPC0gdGVtcCRQVkkKdGVtcCRQVkkgPC0gTlVMTAoKZGV0YWNoKHRlbXApCgojIE1ha2luZyBzZWxlY3Rpb24gdmFyaWFibGUKYXR0YWNoKHRlbXApCnRlbXBbLCJTRUxFQ1RJT04iXSA8LSAibm90X3NlbGVjdGVkIgp0ZW1wJFNFTEVDVElPTlsoUUMyMDE4X0ZJTFRFUj09InBhc3NlZCIgfCBRQzIwMThfRklMVEVSPT0iZmFtaWx5X2tlZXAiKSAmIChTVFVEWV9UWVBFPT0iQ0VBIiAmIFBDQT09IkVVUiIpXSA8LSAic2VsZWN0ZWQiCmRldGFjaCh0ZW1wKQp0YWJsZSh0ZW1wJFNFTEVDVElPTiwgdGVtcCRRQzIwMThfRklMVEVSKQp0YWJsZSh0ZW1wJFNFTEVDVElPTiwgdGVtcCRTVFVEWV9UWVBFKQp0YWJsZSh0ZW1wJFNFTEVDVElPTiwgdGVtcCRQQ0EpCnRhYmxlKHRlbXAkUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXgpCgpgYGAKCgpgYGB7ciBTYXZlIFNhbXBsZVNlbGVjdH0KIyBDaGVjayBodHRwczovL3d3dy53ZWxsLm94LmFjLnVrL35nYXYvc25wdGVzdC8jbXVsdGlub21pYWxfdGVzdHMgZm9yIGRldGFpbHMgb24gbXVsdGlwbGUgY2F0ZWdvcmllcyB0ZXN0aW5nIGluIFNOUFRFU1QKCkFFR1MxMjNfc2FtcGxlLmxpc3QgPC0gdGVtcFtvcmRlcih0ZW1wJE9yaWdpbmFsT3JkZXJfcG9zdE1pY2hJbXBfUUMpLF0KCkFFR1MxMjNfc2FtcGxlLmxpc3QkbWlzc2luZyA8LSAwCgpzYW1wbGVfZmlsZV9hZWdzIDwtIGRwbHlyOjpzZWxlY3QoQUVHUzEyM19zYW1wbGUubGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEXzEsIElEXzIsIG1pc3NpbmcsICMgSURfMiBpcyB0aGUgb3JkZXIgb2Ygc2FtcGxlcyAtIHRoYXQgd2F5IHdlIGFsd2F5cyBrbm93IHdoYXQgdGhlIG9yZGVyIHNob3VsZCBiZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVBJRCwgU1RVRFlfTlVNQkVSLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFFDMjAxOF9GSU5BTCwgUUMyMDE4X0ZJTFRFUiwgU0VMRUNUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQUVHU190eXBlLCBDSElQLCBTVFVEWV9UWVBFLCBTQU1QTEVfVFlQRSwgUENBLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEMxLCBQQzIsIFBDMywgUEM0LCBQQzUsIFBDNiwgUEM3LCBQQzgsIFBDOSwgUEMxMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNleCwgQWdlLCBPUnllYXIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2FsY2lmaWNhdGlvbiwgQ29sbGFnZW4sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmF0MTAsIEZhdDQwLCBJUEgsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU01DX3JhbmtOb3JtLCBNQUNfcmFua05vcm0sIE5ldXRyb3BoaWxzX3JhbmtOb3JtLCBNYXN0Q2VsbHNfcmFua05vcm0sIFZlc3NlbERlbnNpdHlfcmFua05vcm0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBDU0s5X3BsYXNtYSwgUENTSzlfcGxhc21hX3JhbmtOb3JtKSAgJT4lCiAgbXV0YXRlX2lmKGlzLm51bWVyaWMsIGFzLmNoYXJhY3RlcikgJT4lCiAgbXV0YXRlKFNBTVBMRV9UWVBFID0gZ3N1YignICcsICdfJywgU0FNUExFX1RZUEUpKSAlPiUKICBhZGRfcm93KC5iZWZvcmUgPSAxLCAKICAgICAgICAgIElEXzEgPSAiMCIsIElEXzIgPSAiMCIsIG1pc3NpbmcgPSAiMCIsIAogICAgICAgICAgVVBJRCA9ICJEIiwgU1RVRFlfTlVNQkVSID0gIkMiLAogICAgICAgICAgUUMyMDE4X0ZJTkFMID0gIkQiLCBRQzIwMThfRklMVEVSID0gIkQiLCBTRUxFQ1RJT04gPSAiRCIsCiAgICAgICAgICBBRUdTX3R5cGUgPSAiRCIsIENISVAgPSAiRCIsIFNUVURZX1RZUEUgPSAiRCIsIFNBTVBMRV9UWVBFID0gIkQiLCBQQ0EgPSAiRCIsCiAgICAgICAgICBQQzEgPSAiQyIsIFBDMiA9ICJDIiwgUEMzID0gIkMiLCBQQzQgPSAiQyIsIFBDNSA9ICJDIiwgUEM2ID0gIkMiLCBQQzcgPSAiQyIsIFBDOCA9ICJDIiwgUEM5ID0gIkMiLCBQQzEwID0gIkMiLAogICAgICAgICAgU2V4ID0gIkQiLCBBZ2UgPSAiQyIsIE9SeWVhciA9ICJDIiwgCiAgICAgICAgICBDYWxjaWZpY2F0aW9uID0gIkIiLCBDb2xsYWdlbiA9ICJCIiwgCiAgICAgICAgICBGYXQxMCA9ICJCIiwgRmF0NDAgPSAiQiIsIElQSCA9ICJCIiwgCiAgICAgICAgICBTTUNfcmFua05vcm0gPSAiUCIsIE1BQ19yYW5rTm9ybSA9ICJQIiwgTmV1dHJvcGhpbHNfcmFua05vcm0gPSAiUCIsIE1hc3RDZWxsc19yYW5rTm9ybSA9ICJQIiwgVmVzc2VsRGVuc2l0eV9yYW5rTm9ybSA9ICJQIiwKICAgICAgICAgIFBsYXF1ZV9WdWxuZXJhYmlsaXR5X0luZGV4ID0gIkQiLAogICAgICAgICAgUENTSzlfcGxhc21hID0gIlAiLCBQQ1NLOV9wbGFzbWFfcmFua05vcm0gPSAiUCIpICU+JSAjIyBpZGVudGlmaWVyczogaW5kZXggZm9yIHRoZXNlIGlzIDEsIGFuZCBhbGwgYmFzZSB2YXJpYWJsZXMgaGF2ZSAwIGFzIGlkZW50aWZpZXIKICBwcmludCgpCmRpbShzYW1wbGVfZmlsZV9hZWdzKQoKZndyaXRlKHNhbXBsZV9maWxlX2FlZ3MsCiAgICAgICBmaWxlID0gcGFzdGUwKFNOUF9sb2MsICIvIixUb2RheSwiLiIsUFJPSkVDVE5BTUUsIi5BRUdTMTIzLnNhbXBsZSIpLAogICAgICAgbmEgPSAiTkEiLCBzZXAgPSAiXHQiLCBxdW90ZSA9IEZBTFNFLAogICAgICAgcm93Lm5hbWVzID0gRkFMU0UsIGNvbC5uYW1lcyA9IFRSVUUsCiAgICAgICBzaG93UHJvZ3Jlc3MgPSBUUlVFLCB2ZXJib3NlID0gVFJVRSkKCnJlcXVpcmUoRFQpCkRUOjpkYXRhdGFibGUoc2FtcGxlX2ZpbGVfYWVncywgY2FwdGlvbiA9ICJBRUdTOiBmaW5hbCBzYW1wbGUgbGlzdCBvZiBnZW5vdHlwZWQgQUUgcGF0aWVudHMgYWZ0ZXIgcXVhbGl0eSBjb250cm9sLiIsIHJvd25hbWVzID0gRkFMU0UpCgpybSh0ZW1wLCB0ZW1wMiwgdGVtcDMpCmBgYAoKCiMjIyBGZW1hbGVzIG9ubHkKClRoaXMgaXMgdGhlIHNlbGVjdGlvbiBmb3IgZmVtYWxlcyBvbmx5LgoKYGBge3IgVEVNUCBTYW1wbGVTZWxlY3QgRkVNQUxFU30KcmVxdWlyZShvcGVueGxzeCkKCnRlbXAgPC0gc3Vic2V0KEFFR1MsCiAgICAgICAgICAgICAgIEdXQVMgPT0gImdlbm90eXBlZCIsCiAgICAgICAgICAgICAgIHNlbGVjdCA9IGMoIklEXzEiLCAiSURfMiIsICJVUElEIiwgIlNUVURZX05VTUJFUiIsICMgSURfMiBpcyB0aGUgb3JkZXIgb2Ygc2FtcGxlcyEKICAgICAgICAgICAgICAgICAgICAgICAgICAiUUMyMDE4X0ZJTkFMIiwgIlFDMjAxOF9GSUxURVIiLCAiT3JpZ2luYWxPcmRlcl9wb3N0TWljaEltcF9RQyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkFFR1NfdHlwZSIsICJDSElQIiwgIlNUVURZX1RZUEUiLCAiU0FNUExFX1RZUEUiLCAiUENBIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiUEMxIiwgIlBDMiIsICJQQzMiLCAiUEM0IiwgIlBDNSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlBDNiIsICJQQzciLCAiUEM4IiwgIlBDOSIsICJQQzEwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiU2V4IiwgIkFnZSIsICJPUnllYXIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAiQk1JIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2FsYy5iaW4iLCAiQ29sbGFnZW4uYmluIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkZhdC5iaW5fMTAiLCAiRmF0LmJpbl80MCIsICJJUEguYmluIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlNNQ19yYW5rTm9ybSIsICJNQUNfcmFua05vcm0iLCAiTmV1dHJvcGhpbHNfcmFua05vcm0iLCAiTWFzdENlbGxzX3JhbmtOb3JtIiwgIlZlc3NlbERlbnNpdHlfcmFua05vcm0iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAiT3ZlcmFsbFBsYXF1ZVBoZW5vdHlwZSIsICJQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlBDU0s5X3BsYXNtYSIsICJQQ1NLOV9wbGFzbWFfcmFua05vcm0iKSkgIyBTZWxlY3Qgc29tZSBwaGVub3R5cGUgb2YgaW50ZXJlc3QKZGltKHRlbXApCgojIEZpeCB0aGluZ3MKYXR0YWNoKHRlbXApCgp0ZW1wWywiQ2FsY2lmaWNhdGlvbiJdIDwtIE5BCnRlbXAkQ2FsY2lmaWNhdGlvbltDYWxjLmJpbiA9PSAibm8vbWlub3IiXSA8LSAiY29udHJvbCIKdGVtcCRDYWxjaWZpY2F0aW9uW0NhbGMuYmluID09ICJtb2RlcmF0ZS9oZWF2eSJdIDwtICJjYXNlIgoKdGVtcFssIkNvbGxhZ2VuIl0gPC0gTkEKdGVtcCRDb2xsYWdlbltDb2xsYWdlbi5iaW4gPT0gIm5vL21pbm9yIl0gPC0gImNvbnRyb2wiCnRlbXAkQ29sbGFnZW5bQ29sbGFnZW4uYmluID09ICJtb2RlcmF0ZS9oZWF2eSJdIDwtICJjYXNlIgoKdGVtcFssIkZhdDEwIl0gPC0gTkEKdGVtcCRGYXQxMFtGYXQuYmluXzEwID09ICI8MTAlIl0gPC0gImNvbnRyb2wiCnRlbXAkRmF0MTBbRmF0LmJpbl8xMCA9PSAiPjEwJSJdIDwtICJjYXNlIgoKdGVtcFssIkZhdDQwIl0gPC0gTkEKdGVtcCRGYXQ0MFtGYXQuYmluXzQwID09ICI8NDAlIl0gPC0gImNvbnRyb2wiCnRlbXAkRmF0NDBbRmF0LmJpbl80MCA9PSAiPjQwJSJdIDwtICJjYXNlIgoKdGVtcFssIklQSCJdIDwtIE5BCnRlbXAkSVBIW0lQSC5iaW4gPT0gIm5vIl0gPC0gImNvbnRyb2wiCnRlbXAkSVBIW0lQSC5iaW4gPT0gInllcyJdIDwtICJjYXNlIgoKdGVtcFssIlBWSSJdIDwtIE5BCnRlbXAkUFZJW1BsYXF1ZV9WdWxuZXJhYmlsaXR5X0luZGV4ID09ICIwIl0gPC0gIlBWSV9jYXQwIgp0ZW1wJFBWSVtQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCA9PSAiMSJdIDwtICJQVklfY2F0MSIKdGVtcCRQVklbUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXggPT0gIjIiXSA8LSAiUFZJX2NhdDIiCnRlbXAkUFZJW1BsYXF1ZV9WdWxuZXJhYmlsaXR5X0luZGV4ID09ICIzIl0gPC0gIlBWSV9jYXQzIgp0ZW1wJFBWSVtQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCA9PSAiNCJdIDwtICJQVklfY2F0NCIKdGVtcCRQVklbUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXggPT0gIjUiXSA8LSAiUFZJX2NhdDUiCgp0ZW1wJFBsYXF1ZV9WdWxuZXJhYmlsaXR5X0luZGV4IDwtIHRlbXAkUFZJCnRlbXAkUFZJIDwtIE5VTEwKCmRldGFjaCh0ZW1wKQoKIyBNYWtpbmcgc2VsZWN0aW9uIHZhcmlhYmxlCmF0dGFjaCh0ZW1wKQp0ZW1wWywiU0VMRUNUSU9OIl0gPC0gIm5vdF9zZWxlY3RlZCIKdGVtcCRTRUxFQ1RJT05bKFFDMjAxOF9GSUxURVI9PSJwYXNzZWQiIHwgUUMyMDE4X0ZJTFRFUj09ImZhbWlseV9rZWVwIikgJiAoU1RVRFlfVFlQRT09IkNFQSIgJiBQQ0E9PSJFVVIiKSAmIFNleD09IkYiXSA8LSAic2VsZWN0ZWQiCmRldGFjaCh0ZW1wKQp0YWJsZSh0ZW1wJFNFTEVDVElPTiwgdGVtcCRRQzIwMThfRklMVEVSKQp0YWJsZSh0ZW1wJFNFTEVDVElPTiwgdGVtcCRTVFVEWV9UWVBFKQp0YWJsZSh0ZW1wJFNFTEVDVElPTiwgdGVtcCRQQ0EpCmBgYAoKCmBgYHtyIFNhdmUgU2FtcGxlU2VsZWN0IEZFTUFMRVN9CkFFR1MxMjNfc2FtcGxlLmxpc3QgPC0gdGVtcFtvcmRlcih0ZW1wJE9yaWdpbmFsT3JkZXJfcG9zdE1pY2hJbXBfUUMpLF0KCkFFR1MxMjNfc2FtcGxlLmxpc3QkbWlzc2luZyA8LSAwCgpzYW1wbGVfZmlsZV9hZWdzRiA8LSBkcGx5cjo6c2VsZWN0KEFFR1MxMjNfc2FtcGxlLmxpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRF8xLCBJRF8yLCBtaXNzaW5nLCAjIElEXzIgaXMgdGhlIG9yZGVyIG9mIHNhbXBsZXMgLSB0aGF0IHdheSB3ZSBhbHdheXMga25vdyB3aGF0IHRoZSBvcmRlciBzaG91bGQgYmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVQSUQsIFNUVURZX05VTUJFUiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRQzIwMThfRklOQUwsIFFDMjAxOF9GSUxURVIsIFNFTEVDVElPTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFFR1NfdHlwZSwgQ0hJUCwgU1RVRFlfVFlQRSwgU0FNUExFX1RZUEUsIFBDQSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBDMSwgUEMyLCBQQzMsIFBDNCwgUEM1LCBQQzYsIFBDNywgUEM4LCBQQzksIFBDMTAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXgsIEFnZSwgT1J5ZWFyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENhbGNpZmljYXRpb24sIENvbGxhZ2VuLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZhdDEwLCBGYXQ0MCwgSVBILCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNNQ19yYW5rTm9ybSwgTUFDX3JhbmtOb3JtLCBOZXV0cm9waGlsc19yYW5rTm9ybSwgTWFzdENlbGxzX3JhbmtOb3JtLCBWZXNzZWxEZW5zaXR5X3JhbmtOb3JtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQ1NLOV9wbGFzbWEsIFBDU0s5X3BsYXNtYV9yYW5rTm9ybSkgICU+JQogIG11dGF0ZV9pZihpcy5udW1lcmljLCBhcy5jaGFyYWN0ZXIpICU+JQogIG11dGF0ZShTQU1QTEVfVFlQRSA9IGdzdWIoJyAnLCAnXycsIFNBTVBMRV9UWVBFKSkgJT4lCiAgYWRkX3JvdyguYmVmb3JlID0gMSwgCiAgICAgICAgICBJRF8xID0gIjAiLCBJRF8yID0gIjAiLCBtaXNzaW5nID0gIjAiLCAKICAgICAgICAgIFVQSUQgPSAiRCIsIFNUVURZX05VTUJFUiA9ICJDIiwKICAgICAgICAgIFFDMjAxOF9GSU5BTCA9ICJEIiwgUUMyMDE4X0ZJTFRFUiA9ICJEIiwgU0VMRUNUSU9OID0gIkQiLAogICAgICAgICAgQUVHU190eXBlID0gIkQiLCBDSElQID0gIkQiLCBTVFVEWV9UWVBFID0gIkQiLCBTQU1QTEVfVFlQRSA9ICJEIiwgUENBID0gIkQiLAogICAgICAgICAgUEMxID0gIkMiLCBQQzIgPSAiQyIsIFBDMyA9ICJDIiwgUEM0ID0gIkMiLCBQQzUgPSAiQyIsIFBDNiA9ICJDIiwgUEM3ID0gIkMiLCBQQzggPSAiQyIsIFBDOSA9ICJDIiwgUEMxMCA9ICJDIiwKICAgICAgICAgIFNleCA9ICJEIiwgQWdlID0gIkMiLCBPUnllYXIgPSAiQyIsIAogICAgICAgICAgQ2FsY2lmaWNhdGlvbiA9ICJCIiwgQ29sbGFnZW4gPSAiQiIsIAogICAgICAgICAgRmF0MTAgPSAiQiIsIEZhdDQwID0gIkIiLCBJUEggPSAiQiIsIAogICAgICAgICAgU01DX3JhbmtOb3JtID0gIlAiLCBNQUNfcmFua05vcm0gPSAiUCIsIE5ldXRyb3BoaWxzX3JhbmtOb3JtID0gIlAiLCBNYXN0Q2VsbHNfcmFua05vcm0gPSAiUCIsIFZlc3NlbERlbnNpdHlfcmFua05vcm0gPSAiUCIsCiAgICAgICAgICBQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCA9ICJEIiwKICAgICAgICAgIFBDU0s5X3BsYXNtYSA9ICJQIiwgUENTSzlfcGxhc21hX3JhbmtOb3JtID0gIlAiKSAlPiUgIyMgaWRlbnRpZmllcnM6IGluZGV4IGZvciB0aGVzZSBpcyAxLCBhbmQgYWxsIGJhc2UgdmFyaWFibGVzIGhhdmUgMCBhcyBpZGVudGlmaWVyCiAgcHJpbnQoKQpkaW0oc2FtcGxlX2ZpbGVfYWVnc0YpCgpmd3JpdGUoc2FtcGxlX2ZpbGVfYWVnc0YsCiAgICAgICBmaWxlID0gcGFzdGUwKFNOUF9sb2MsICIvIixUb2RheSwiLiIsUFJPSkVDVE5BTUUsIi5BRUdTMTIzLmZlbWFsZXMuc2FtcGxlIiksCiAgICAgICBuYSA9ICJOQSIsIHNlcCA9ICJcdCIsIHF1b3RlID0gRkFMU0UsCiAgICAgICByb3cubmFtZXMgPSBGQUxTRSwgY29sLm5hbWVzID0gVFJVRSwKICAgICAgIHNob3dQcm9ncmVzcyA9IFRSVUUsIHZlcmJvc2UgPSBUUlVFKQoKcmVxdWlyZShEVCkKRFQ6OmRhdGF0YWJsZShzYW1wbGVfZmlsZV9hZWdzRiwgY2FwdGlvbiA9ICJBRUdTOiBmaW5hbCBzYW1wbGUgbGlzdCBvZiBnZW5vdHlwZWQgQUUgcGF0aWVudHMgYWZ0ZXIgcXVhbGl0eSBjb250cm9sLiIsIHJvd25hbWVzID0gRkFMU0UpCgpybSh0ZW1wKQpgYGAKCiMjIyBNYWxlcyBvbmx5CgpUaGlzIGlzIHRoZSBzZWxlY3Rpb24gZm9yIG1hbGVzIG9ubHkuCgpgYGB7ciBURU1QIFNhbXBsZVNlbGVjdCBNQUxFU30KcmVxdWlyZShvcGVueGxzeCkKCnRlbXAgPC0gc3Vic2V0KEFFR1MsCiAgICAgICAgICAgICAgIEdXQVMgPT0gImdlbm90eXBlZCIsCiAgICAgICAgICAgICAgIHNlbGVjdCA9IGMoIklEXzEiLCAiSURfMiIsICJVUElEIiwgIlNUVURZX05VTUJFUiIsICMgSURfMiBpcyB0aGUgb3JkZXIgb2Ygc2FtcGxlcyEKICAgICAgICAgICAgICAgICAgICAgICAgICAiUUMyMDE4X0ZJTkFMIiwgIlFDMjAxOF9GSUxURVIiLCAiT3JpZ2luYWxPcmRlcl9wb3N0TWljaEltcF9RQyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkFFR1NfdHlwZSIsICJDSElQIiwgIlNUVURZX1RZUEUiLCAiU0FNUExFX1RZUEUiLCAiUENBIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiUEMxIiwgIlBDMiIsICJQQzMiLCAiUEM0IiwgIlBDNSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlBDNiIsICJQQzciLCAiUEM4IiwgIlBDOSIsICJQQzEwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiU2V4IiwgIkFnZSIsICJPUnllYXIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAiQk1JIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2FsYy5iaW4iLCAiQ29sbGFnZW4uYmluIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkZhdC5iaW5fMTAiLCAiRmF0LmJpbl80MCIsICJJUEguYmluIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlNNQ19yYW5rTm9ybSIsICJNQUNfcmFua05vcm0iLCAiTmV1dHJvcGhpbHNfcmFua05vcm0iLCAiTWFzdENlbGxzX3JhbmtOb3JtIiwgIlZlc3NlbERlbnNpdHlfcmFua05vcm0iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAiT3ZlcmFsbFBsYXF1ZVBoZW5vdHlwZSIsICJQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlBDU0s5X3BsYXNtYSIsICJQQ1NLOV9wbGFzbWFfcmFua05vcm0iKSkgIyBTZWxlY3Qgc29tZSBwaGVub3R5cGUgb2YgaW50ZXJlc3QKZGltKHRlbXApCgojIEZpeCB0aGluZ3MKYXR0YWNoKHRlbXApCgp0ZW1wWywiQ2FsY2lmaWNhdGlvbiJdIDwtIE5BCnRlbXAkQ2FsY2lmaWNhdGlvbltDYWxjLmJpbiA9PSAibm8vbWlub3IiXSA8LSAiY29udHJvbCIKdGVtcCRDYWxjaWZpY2F0aW9uW0NhbGMuYmluID09ICJtb2RlcmF0ZS9oZWF2eSJdIDwtICJjYXNlIgoKdGVtcFssIkNvbGxhZ2VuIl0gPC0gTkEKdGVtcCRDb2xsYWdlbltDb2xsYWdlbi5iaW4gPT0gIm5vL21pbm9yIl0gPC0gImNvbnRyb2wiCnRlbXAkQ29sbGFnZW5bQ29sbGFnZW4uYmluID09ICJtb2RlcmF0ZS9oZWF2eSJdIDwtICJjYXNlIgoKdGVtcFssIkZhdDEwIl0gPC0gTkEKdGVtcCRGYXQxMFtGYXQuYmluXzEwID09ICI8MTAlIl0gPC0gImNvbnRyb2wiCnRlbXAkRmF0MTBbRmF0LmJpbl8xMCA9PSAiPjEwJSJdIDwtICJjYXNlIgoKdGVtcFssIkZhdDQwIl0gPC0gTkEKdGVtcCRGYXQ0MFtGYXQuYmluXzQwID09ICI8NDAlIl0gPC0gImNvbnRyb2wiCnRlbXAkRmF0NDBbRmF0LmJpbl80MCA9PSAiPjQwJSJdIDwtICJjYXNlIgoKdGVtcFssIklQSCJdIDwtIE5BCnRlbXAkSVBIW0lQSC5iaW4gPT0gIm5vIl0gPC0gImNvbnRyb2wiCnRlbXAkSVBIW0lQSC5iaW4gPT0gInllcyJdIDwtICJjYXNlIgoKdGVtcFssIlBWSSJdIDwtIE5BCnRlbXAkUFZJW1BsYXF1ZV9WdWxuZXJhYmlsaXR5X0luZGV4ID09ICIwIl0gPC0gIlBWSV9jYXQwIgp0ZW1wJFBWSVtQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCA9PSAiMSJdIDwtICJQVklfY2F0MSIKdGVtcCRQVklbUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXggPT0gIjIiXSA8LSAiUFZJX2NhdDIiCnRlbXAkUFZJW1BsYXF1ZV9WdWxuZXJhYmlsaXR5X0luZGV4ID09ICIzIl0gPC0gIlBWSV9jYXQzIgp0ZW1wJFBWSVtQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCA9PSAiNCJdIDwtICJQVklfY2F0NCIKdGVtcCRQVklbUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXggPT0gIjUiXSA8LSAiUFZJX2NhdDUiCgp0ZW1wJFBsYXF1ZV9WdWxuZXJhYmlsaXR5X0luZGV4IDwtIHRlbXAkUFZJCnRlbXAkUFZJIDwtIE5VTEwKCmRldGFjaCh0ZW1wKQoKIyBNYWtpbmcgc2VsZWN0aW9uIHZhcmlhYmxlCmF0dGFjaCh0ZW1wKQp0ZW1wWywiU0VMRUNUSU9OIl0gPC0gIm5vdF9zZWxlY3RlZCIKdGVtcCRTRUxFQ1RJT05bKFFDMjAxOF9GSUxURVI9PSJwYXNzZWQiIHwgUUMyMDE4X0ZJTFRFUj09ImZhbWlseV9rZWVwIikgJiAoU1RVRFlfVFlQRT09IkNFQSIgJiBQQ0E9PSJFVVIiKSAmIFNleD09Ik0iXSA8LSAic2VsZWN0ZWQiCmRldGFjaCh0ZW1wKQp0YWJsZSh0ZW1wJFNFTEVDVElPTiwgdGVtcCRRQzIwMThfRklMVEVSKQp0YWJsZSh0ZW1wJFNFTEVDVElPTiwgdGVtcCRTVFVEWV9UWVBFKQp0YWJsZSh0ZW1wJFNFTEVDVElPTiwgdGVtcCRQQ0EpCmBgYAoKCmBgYHtyIFNhdmUgU2FtcGxlU2VsZWN0IE1BTEVTfQpBRUdTMTIzX3NhbXBsZS5saXN0IDwtIHRlbXBbb3JkZXIodGVtcCRPcmlnaW5hbE9yZGVyX3Bvc3RNaWNoSW1wX1FDKSxdCgpBRUdTMTIzX3NhbXBsZS5saXN0JG1pc3NpbmcgPC0gMAoKc2FtcGxlX2ZpbGVfYWVnc00gPC0gZHBseXI6OnNlbGVjdChBRUdTMTIzX3NhbXBsZS5saXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURfMSwgSURfMiwgbWlzc2luZywgIyBJRF8yIGlzIHRoZSBvcmRlciBvZiBzYW1wbGVzIC0gdGhhdCB3YXkgd2UgYWx3YXlzIGtub3cgd2hhdCB0aGUgb3JkZXIgc2hvdWxkIGJlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVUElELCBTVFVEWV9OVU1CRVIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUUMyMDE4X0ZJTkFMLCBRQzIwMThfRklMVEVSLCBTRUxFQ1RJT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBRUdTX3R5cGUsIENISVAsIFNUVURZX1RZUEUsIFNBTVBMRV9UWVBFLCBQQ0EsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQzEsIFBDMiwgUEMzLCBQQzQsIFBDNSwgUEM2LCBQQzcsIFBDOCwgUEM5LCBQQzEwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2V4LCBBZ2UsIE9SeWVhciwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDYWxjaWZpY2F0aW9uLCBDb2xsYWdlbiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGYXQxMCwgRmF0NDAsIElQSCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTUNfcmFua05vcm0sIE1BQ19yYW5rTm9ybSwgTmV1dHJvcGhpbHNfcmFua05vcm0sIE1hc3RDZWxsc19yYW5rTm9ybSwgVmVzc2VsRGVuc2l0eV9yYW5rTm9ybSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBsYXF1ZV9WdWxuZXJhYmlsaXR5X0luZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUENTSzlfcGxhc21hLCBQQ1NLOV9wbGFzbWFfcmFua05vcm0pICAlPiUKICBtdXRhdGVfaWYoaXMubnVtZXJpYywgYXMuY2hhcmFjdGVyKSAlPiUKICBtdXRhdGUoU0FNUExFX1RZUEUgPSBnc3ViKCcgJywgJ18nLCBTQU1QTEVfVFlQRSkpICU+JQogIGFkZF9yb3coLmJlZm9yZSA9IDEsIAogICAgICAgICAgSURfMSA9ICIwIiwgSURfMiA9ICIwIiwgbWlzc2luZyA9ICIwIiwgCiAgICAgICAgICBVUElEID0gIkQiLCBTVFVEWV9OVU1CRVIgPSAiQyIsCiAgICAgICAgICBRQzIwMThfRklOQUwgPSAiRCIsIFFDMjAxOF9GSUxURVIgPSAiRCIsIFNFTEVDVElPTiA9ICJEIiwKICAgICAgICAgIEFFR1NfdHlwZSA9ICJEIiwgQ0hJUCA9ICJEIiwgU1RVRFlfVFlQRSA9ICJEIiwgU0FNUExFX1RZUEUgPSAiRCIsIFBDQSA9ICJEIiwKICAgICAgICAgIFBDMSA9ICJDIiwgUEMyID0gIkMiLCBQQzMgPSAiQyIsIFBDNCA9ICJDIiwgUEM1ID0gIkMiLCBQQzYgPSAiQyIsIFBDNyA9ICJDIiwgUEM4ID0gIkMiLCBQQzkgPSAiQyIsIFBDMTAgPSAiQyIsCiAgICAgICAgICBTZXggPSAiRCIsIEFnZSA9ICJDIiwgT1J5ZWFyID0gIkMiLCAKICAgICAgICAgIENhbGNpZmljYXRpb24gPSAiQiIsIENvbGxhZ2VuID0gIkIiLCAKICAgICAgICAgIEZhdDEwID0gIkIiLCBGYXQ0MCA9ICJCIiwgSVBIID0gIkIiLCAKICAgICAgICAgIFNNQ19yYW5rTm9ybSA9ICJQIiwgTUFDX3JhbmtOb3JtID0gIlAiLCBOZXV0cm9waGlsc19yYW5rTm9ybSA9ICJQIiwgTWFzdENlbGxzX3JhbmtOb3JtID0gIlAiLCBWZXNzZWxEZW5zaXR5X3JhbmtOb3JtID0gIlAiLAogICAgICAgICAgUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXggPSAiRCIsCiAgICAgICAgICBQQ1NLOV9wbGFzbWEgPSAiUCIsIFBDU0s5X3BsYXNtYV9yYW5rTm9ybSA9ICJQIikgJT4lICMjIGlkZW50aWZpZXJzOiBpbmRleCBmb3IgdGhlc2UgaXMgMSwgYW5kIGFsbCBiYXNlIHZhcmlhYmxlcyBoYXZlIDAgYXMgaWRlbnRpZmllcgogIHByaW50KCkKZGltKHNhbXBsZV9maWxlX2FlZ3NNKQoKCmZ3cml0ZShzYW1wbGVfZmlsZV9hZWdzTSwKICAgICAgIGZpbGUgPSBwYXN0ZTAoU05QX2xvYywgIi8iLFRvZGF5LCIuIixQUk9KRUNUTkFNRSwiLkFFR1MxMjMubWFsZXMuc2FtcGxlIiksCiAgICAgICBuYSA9ICJOQSIsIHNlcCA9ICJcdCIsIHF1b3RlID0gRkFMU0UsCiAgICAgICByb3cubmFtZXMgPSBGQUxTRSwgY29sLm5hbWVzID0gVFJVRSwKICAgICAgIHNob3dQcm9ncmVzcyA9IFRSVUUsIHZlcmJvc2UgPSBUUlVFKQoKcmVxdWlyZShEVCkKRFQ6OmRhdGF0YWJsZShzYW1wbGVfZmlsZV9hZWdzTSwgY2FwdGlvbiA9ICJBRUdTOiBmaW5hbCBzYW1wbGUgbGlzdCBvZiBnZW5vdHlwZWQgQUUgcGF0aWVudHMgYWZ0ZXIgcXVhbGl0eSBjb250cm9sLiIsIHJvd25hbWVzID0gRkFMU0UpCgpybSh0ZW1wKQpgYGAKCiMjIFgtY2hyb21vc29tZSBkYXRhCgpUaGUgWC1jaHJvbW9zb21lIGRhdGEgaXMgdGFrZW4gZnJvbSBwcmV2aW91c2x5IGltcHV0ZWQgZGF0YSBiYXNlZCBvbiAxMDAwRyBwaGFzZSAzICh2ZXJzaW9uIDUpIGFuZCBHb05MNS4gRm9yIHNvbWUgcmVhc29uLCBpbXB1dGluZyBvbiB0aGUgTWljaGlnYW4gSW1wdXRhdGlvbiBTZXJ2ZXIgd2FzIG5vdCBzdWNjZXNzZnVsICgqQUNUSU9OIHBvaW50KikuCgpIZXJlIHdlIGxvYWQgaW4gdGhlIHNhbXBsZSBmaWxlcyBmb3IgdGhlIHRocmVlIGRhdGFzZXRzIG9mIHRoZSBYIGNocm9tb3NvbWFsIGRhdGEuIFdlIHNob3VsZDoKCi0gZmlsdGVyIG91dCBzYW1wbGVzIHRoYXQgZGlkIG5vdCBwYXNzIHF1YWxpdHkgY29udHJvbCwgZW5kaW5nIHVwIHdpdGggMiwxMjQgc2FtcGxlCi0gcmUtb3JkZXIgdGhlIGRhdGEgdG8gZml0IHRoZSBvdGhlciBhdXRvc29tYWwgZGF0YS4KCgpgYGB7ciBTYW1wbGVMaXN0IFh9CgpBRUdTMTIzX2NoclggPC0gZnJlYWQocGFzdGUwKE1JQ0hJTVBfbG9jLCAiL19jaHIyM18xa2dfZ29ubDUvYWVncy5yYXcuMWtnX2dvbmw1LmNocjIzLm1hcHBpbmdzLnR4dCIpKQpuYW1lcyhBRUdTMTIzX2NoclgpW25hbWVzKEFFR1MxMjNfY2hyWCkgPT0gIklEXzEiXSA8LSAiU2FtcGxlSURfcG9zdEltcENoclgiCgpBRUdTMTIzX0FsbENociA8LSBtZXJnZShBRUdTMTIzX2NoclgsIHNhbXBsZV9maWxlX2FlZ3MsIGJ5LnggPSAiU2FtcGxlSURfcG9zdE1pY2hJbXAiLCBieS55ID0gIklEXzEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgYWxsLnggPSBUUlVFLCAKICAgICAgICAgICAgICAgICAgICAgICAgc29ydCA9IEZBTFNFKQoKbmFtZXMoQUVHUzEyM19BbGxDaHIpW25hbWVzKEFFR1MxMjNfQWxsQ2hyKSA9PSAiSURfMi55Il0gPC0gIklEXzIiCm5hbWVzKEFFR1MxMjNfQWxsQ2hyKVtuYW1lcyhBRUdTMTIzX0FsbENocikgPT0gIlNUVURZX1RZUEUueSJdIDwtICJTVFVEWV9UWVBFIgpuYW1lcyhBRUdTMTIzX0FsbENocilbbmFtZXMoQUVHUzEyM19BbGxDaHIpID09ICJTYW1wbGVJRF9wb3N0TWljaEltcCJdIDwtICJJRF8xIgpBRUdTMTIzX0FsbENociRtaXNzaW5nLnggPC0gTlVMTApBRUdTMTIzX0FsbENociRtaXNzaW5nLnkgPC0gTlVMTApBRUdTMTIzX0FsbENociRTVFVEWV9UWVBFLnggPC0gTlVMTApBRUdTMTIzX0FsbENociRJRF8yLnggPC0gTlVMTAoKZGltKEFFR1MxMjNfQWxsQ2hyKQpzdHIoQUVHUzEyM19BbGxDaHIpCmBgYAoKVGhpcyBzZWVtcyBmaW5lLCBsZXQncyBmaWx0ZXI7IHdlIGNhbiB1c2UgdGhpcyBmaWxlIHRvIGZpbHRlciB0aGUgZ2VuZXRpYyBkYXRhLiBBbmQgd2UgY3JlYXRlIGFub3RoZXIgZmlsZSB0byByZS1vcmRlciB0aGUgZGF0YS4KCmBgYHtyIFNhbXBsZUxpc3QgWDogZmlsdGVyfQoKQUVHUzEyM19BbGxDaHJRQyA8LSBzdWJzZXQoQUVHUzEyM19BbGxDaHIsCiAgICAgICAgICAgICAgICFpcy5uYShRQzIwMThfRklMVEVSKSwKICAgICAgICAgICAgICAgc2VsZWN0ID0gYygiSURfMSIsICJJRF8yIiwgIlVQSUQiLCAiU1RVRFlfTlVNQkVSIiwgIlNhbXBsZUlEX3Bvc3RJbXBDaHJYIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiUUMyMDE4X0ZJTkFMIiwgIlFDMjAxOF9GSUxURVIiLCAiU0VMRUNUSU9OIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiQUVHU190eXBlIiwgIkNISVAiLCAiU1RVRFlfVFlQRSIsICJTQU1QTEVfVFlQRSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlBDMSIsICJQQzIiLCAiUEMzIiwgIlBDNCIsICJQQzUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJQQzYiLCAiUEM3IiwgIlBDOCIsICJQQzkiLCAiUEMxMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlNleCIsICJBZ2UiLCAiT1J5ZWFyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkNhbGNpZmljYXRpb24iLCAiQ29sbGFnZW4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAiRmF0MTAiLCAiRmF0NDAiLCAiSVBIIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlNNQ19yYW5rTm9ybSIsICJNQUNfcmFua05vcm0iLCAiTmV1dHJvcGhpbHNfcmFua05vcm0iLCAiTWFzdENlbGxzX3JhbmtOb3JtIiwgIlZlc3NlbERlbnNpdHlfcmFua05vcm0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICJQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlBDU0s5X3BsYXNtYSIsICJQQ1NLOV9wbGFzbWFfcmFua05vcm0iKSkKCkFFR1MxMjNfQWxsQ2hyUUNfcmVvcmRlciA8LUFFR1MxMjNfQWxsQ2hyUUNbb3JkZXIoQUVHUzEyM19BbGxDaHJRQyRJRF8yKSxdICMgcmVtZW1iZXI6IElEXzIgaXMgdGhlIG9yZGVyIG9mIHNhbXBsZXMKCkFFR1MxMjNfQWxsQ2hyUUNfZmlsdGVyZWQgPC0gc3Vic2V0KEFFR1MxMjNfQWxsQ2hyLAogICAgICAgICAgICAgICBpcy5uYShRQzIwMThfRklMVEVSKSwKICAgICAgICAgICAgICAgc2VsZWN0ID0gYygiSURfMSIsICJJRF8yIiwgIlVQSUQiLCAiU1RVRFlfTlVNQkVSIiwgIlNhbXBsZUlEX3Bvc3RJbXBDaHJYIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiUUMyMDE4X0ZJTkFMIiwgIlFDMjAxOF9GSUxURVIiLCAiU0VMRUNUSU9OIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiQUVHU190eXBlIiwgIkNISVAiLCAiU1RVRFlfVFlQRSIsICJTQU1QTEVfVFlQRSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlBDMSIsICJQQzIiLCAiUEMzIiwgIlBDNCIsICJQQzUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJQQzYiLCAiUEM3IiwgIlBDOCIsICJQQzkiLCAiUEMxMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlNleCIsICJBZ2UiLCAiT1J5ZWFyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkNhbGNpZmljYXRpb24iLCAiQ29sbGFnZW4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAiRmF0MTAiLCAiRmF0NDAiLCAiSVBIIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlNNQ19yYW5rTm9ybSIsICJNQUNfcmFua05vcm0iLCAiTmV1dHJvcGhpbHNfcmFua05vcm0iLCAiTWFzdENlbGxzX3JhbmtOb3JtIiwgIlZlc3NlbERlbnNpdHlfcmFua05vcm0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICJQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlBDU0s5X3BsYXNtYSIsICJQQ1NLOV9wbGFzbWFfcmFua05vcm0iKSkKCmZ3cml0ZShBRUdTMTIzX0FsbENoclFDX3Jlb3JkZXIsCiAgICAgICBmaWxlID0gcGFzdGUwKFNOUF9sb2MsICIvIixUb2RheSwiLiIsUFJPSkVDVE5BTUUsIi5BRUdTMTIzLmNoclguc2FtcGxlIiksCiAgICAgICBuYSA9ICJOQSIsIHNlcCA9ICJcdCIsIHF1b3RlID0gRkFMU0UsCiAgICAgICByb3cubmFtZXMgPSBGQUxTRSwgY29sLm5hbWVzID0gVFJVRSwKICAgICAgIHNob3dQcm9ncmVzcyA9IFRSVUUsIHZlcmJvc2UgPSBUUlVFKQoKcmVxdWlyZShEVCkKRFQ6OmRhdGF0YWJsZShBRUdTMTIzX0FsbENoclFDLCBjYXB0aW9uID0gIkFFR1M6IGZpbmFsIHNhbXBsZSBsaXN0IG9mIGdlbm90eXBlZCBBRSBwYXRpZW50cyBhZnRlciBxdWFsaXR5IGNvbnRyb2wgKGNocm9tb3NvbWUgWCkuIiwgcm93bmFtZXMgPSBGQUxTRSkKCgpgYGAKCiMgR1dBU1Rvb2xLaXQgcHJlcGFyYXRpb24KCiMjIFZhcmlhbnRMaXN0czogdG9wIFNOUHMKCkhlcmUgd2UgY3JlYXRlIGEgYHZhcmlhbnRsaXN0LnR4dGAgZmlsZSB1c2VkIGJ5ICoqR1dBU1Rvb2xLaXQqKiBmb3IgYW5hbHlzaXMuVGhlc2UgYXJlIHRoZSB2YXJpYW50cyB3aXRoIExEIHI8c3VwPjI8L3N1cD4gPT4gMC42IGFyb3VuZCBlYWNoIG9mIHRoZSAxNSB0b3AgU05QcyBhc3NvY2lhdGVkIHdpdGggQ0FDLgoKYGBge3IgY3JlYXRlIHZhcmlhbnRMaXN0fQp2YXJpYW50X2xpc3QKCnRlbXAgPC0gc3Vic2V0KHZhcmlhbnRfbGlzdCwgc2VsZWN0ID0gYygiVmFyaWFudElEIiwgIkNociIsICJCUCIpKQoKZndyaXRlKHRlbXAsCiAgICAgICBmaWxlID0gcGFzdGUwKFNOUF9sb2MsICIvdmFyaWFudGxpc3QudHh0IiksCiAgICAgICBuYSA9ICJOQSIsIHNlcCA9ICJcdCIsIHF1b3RlID0gRkFMU0UsCiAgICAgICByb3cubmFtZXMgPSBGQUxTRSwgY29sLm5hbWVzID0gRkFMU0UsCiAgICAgICBzaG93UHJvZ3Jlc3MgPSBUUlVFLCB2ZXJib3NlID0gVFJVRSkKcm0odGVtcCkKYGBgCjwhLS0gIyMgVmFyaWFudExpc3RzOiBDcmVkaWJsZSBTZXQgLS0+Cgo8IS0tIEhlcmUgd2UgY3JlYXRlIGEgYGNyZWRpYmxlc2V0bGlzdC50eHRgIGZpbGUgdXNlZCBieSAqKkdXQVNUb29sS2l0KiogZm9yIGFuYWx5c2lzLlRoZXNlIGFyZSB0aGUgdmFyaWFudHMgaW4gdGhlIDk1JSBjcmVkaWJsZSBzZXQgb2YgY2F1c2FsIHZhcmlhbnRzIGZvciB0aGUgMTUgdG9wIFNOUHMgYXNzb2NpYXRlZCB3aXRoIENBQy4gLS0+Cgo8IS0tIGBgYHtyIGNyZWF0ZSBjcmVkc2V0X2xpc3R9IC0tPgo8IS0tIGNyZWRzZXRfbGlzdCAtLT4KCjwhLS0gdGVtcCA8LSBzdWJzZXQoY3JlZHNldF9saXN0LCBzZWxlY3QgPSBjKCJWYXJpYW50SUQiLCAiQ2hyIiwgIkJQIikpIC0tPgoKPCEtLSBmd3JpdGUodGVtcCwgLS0+CjwhLS0gICAgICAgIGZpbGUgPSBwYXN0ZTAoU05QX2xvYywgIi9jcmVkaWJsZXNldGxpc3QudHh0IiksIC0tPgo8IS0tICAgICAgICBuYSA9ICJOQSIsIHNlcCA9ICJcdCIsIHF1b3RlID0gRkFMU0UsIC0tPgo8IS0tICAgICAgICByb3cubmFtZXMgPSBGQUxTRSwgY29sLm5hbWVzID0gRkFMU0UsIC0tPgo8IS0tICAgICAgICBzaG93UHJvZ3Jlc3MgPSBUUlVFLCB2ZXJib3NlID0gVFJVRSkgLS0+CjwhLS0gcm0odGVtcCkgLS0+CjwhLS0gYGBgIC0tPgoKIyMgQ292YXJpYXRlcwoKSGVyZSB3ZSBjcmVhdGUgYSBgY292YXJpYXRlcy50eHRgIGZpbGUgdXNlZCBieSAqKkdXQVNUb29sS2l0KiogZm9yIGFuYWx5c2lzLgoKYGBge3IgY3JlYXRlIGNvdmFyaWF0ZXNMaXN0fQpsaWJyYXJ5KHRpZHl2ZXJzZSkKIyBmb3IgJ292ZXJhbGwnIGFuYWx5c2VzCmMoIkFnZSBTZXggUEMxIFBDMiBPUnllYXIiKSAlPiUgd3JpdGVfbGluZXMocGFzdGUwKFNOUF9sb2MsICIvY292YXJpYXRlcy50eHQiKSkKCiMgZm9yIHNleC1zcGVjaWZpYyBhbmFseXNlcwpjKCJBZ2UgUEMxIFBDMiBPUnllYXIiKSAlPiUgd3JpdGVfbGluZXMocGFzdGUwKFNOUF9sb2MsICIvY292YXJpYXRlcy5zZXgudHh0IikpCmBgYAoKIyMgUGhlbm90eXBlcwoKSGVyZSB3ZSBjcmVhdGUgYSBgcGhlbm90eXBlcy50eHRgIGZpbGUgdXNlZCBieSAqKkdXQVNUb29sS2l0KiogZm9yIGFuYWx5c2lzLgoKYGBge3IgY3JlYXRlIHBoZW5vdHlwZXNMaXN0fQpsaWJyYXJ5KHRpZHl2ZXJzZSkKYygiQ2FsY2lmaWNhdGlvbiIsICJDb2xsYWdlbiIsICJGYXQxMCIsICJGYXQ0MCIsICJJUEgiLCAiU01DX3JhbmtOb3JtIiwgIk1BQ19yYW5rTm9ybSIsICJOZXV0cm9waGlsc19yYW5rTm9ybSIsICJNYXN0Q2VsbHNfcmFua05vcm0iLCAiVmVzc2VsRGVuc2l0eV9yYW5rTm9ybSIpICU+JSB3cml0ZV9saW5lcyhwYXN0ZTAoU05QX2xvYywgIi9waGVub3R5cGVzLnR4dCIpKQoKYygiUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXgiKSAlPiUgd3JpdGVfbGluZXMocGFzdGUwKFNOUF9sb2MsICIvcGhlbm90eXBlcy5wdmkudHh0IikpCgoKYGBgCgoKIyBTZXNzaW9uIGluZm9ybWF0aW9uCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBWZXJzaW9uOiAgICAgIHYxLjIuMQogICAgTGFzdCB1cGRhdGU6ICAyMDIzLTA2LTE0CiAgICBXcml0dGVuIGJ5OiAgIFNhbmRlciBXLiB2YW4gZGVyIExhYW4gKHMudy52YW5kZXJsYWFuLTJbYXRddW1jdXRyZWNodC5ubCkuCiAgICBEZXNjcmlwdGlvbjogIFNjcmlwdCB0byBnZXQgc29tZSBBdGhlcm8tRXhwcmVzcyBCaW9iYW5rIFN0dWR5IGJhc2VsaW5lIGNoYXJhY3RlcmlzdGljcy4KICAgIE1pbmltdW0gcmVxdWlyZW1lbnRzOiBSIHZlcnNpb24gMy40LjMgKDIwMTctMDYtMzApIC0tICdTaW5nbGUgQ2FuZGxlJywgTWFjIE9TIFggRWwgQ2FwaXRhbgoKICAgIENoYW5nZXMgbG9nCiAgICAqIHYxLjIuMSBGaXhlZCBpc3N1ZSB3aXRoIGJhc2VsaW5lIHdyaXRpbmcuCiAgICAqIHYxLjIuMCBVcGRhdGUgdG8gdGhlIHN0dWR5IGRhdGFiYXNlLiAKICAgICogdjEuMS4wIE1ham9yIHVwZGF0ZSB0byBXT1JDUyBzeXN0ZW0uIAogICAgKiB2MS4wLjYgU21hbGwgYnVnIGZpeGVzLgogICAgKiB2MS4wLjUgQWRkZWQgcG5nIGZvciBvdmVybGFwLWZpZ3VyZS4KICAgICogdjEuMC41IFJlbW92ZWQgb2Jzb2xldGUgcmVmZXJlbmNlcyB0byBvYmplY3RzLgogICAgKiB2MS4wLjQgRml4ZWQgYSBtaXN0YWtlIGluIHRoZSBjaHIgWCBzYW1wbGUtZmlsZSBjcmVhdGlvbi4gTm93IHRoZSBvcmRlciBtYXRjaGVzIHRoZSBjaHIgWCBkYXRhLgogICAgKiB2MS4wLjMgRml4ZWQgd2VpZ2h0IG9mIGZpbGVzIChsaW1pdCBvZiAxME1iIHBlciBmaWxlIGZvciB0ZW1wbGF0ZXMpLiBSZW5hbWVkIGVudGlyZSByZXBvLgogICAgKiB2MS4wLjIgQWRkZWQgc2V4LXNwZWNpZmljIC5zYW1wbGUtZmlsZXMuIEFkZGVkIEdXQVNUb29sS2l0IGlucHV0LWZpbGVzLgogICAgKiB2MS4wLjAgSW5pdGlhbCB2ZXJzaW9uLiBBZGQgJ3BsYXF1ZSB2dWxuZXJhYmlsaXR5IGluZGV4JywgRml4ZWQgYmFzZWxpbmUgdGFibGUsIGFkZGVkIGNvZGVzLCBhbmQgcmVzdWx0cy4gQ3JlYXRlZCBzYW1wbGUtZmlsZXMuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmBgYHtyIGV2YWwgPSBUUlVFfQpzZXNzaW9uSW5mbygpCmBgYAoKIyBTYXZpbmcgZW52aXJvbm1lbnQKCmBgYHtyIFNhdmluZ30Kc2F2ZS5pbWFnZShwYXN0ZTAoUFJPSkVDVF9sb2MsICIvIixUb2RheSwiLiIsUFJPSkVDVE5BTUUsIi5TTlBfYW5hbHlzZXMuUkRhdGEiKSkKYGBgCgorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCnwgPHN1cD7CqSAxOTc5LTIwMjMgU2FuZGVyIFcuIHZhbiBkZXIgTGFhbiB8IHMudy52YW5kZXJsYWFuW2F0XWdtYWlsLmNvbSB8IFt2YW5kZXJsYWFuLnNjaWVuY2VdKGh0dHBzOi8vdmFuZGVybGFhbi5zY2llbmNlKS48L3N1cD4gfAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCg==